|
|
|
@ -12,7 +12,6 @@ namespace fs = std::filesystem;
|
|
|
|
|
|
|
|
|
|
googleTile::googleTile()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
googleTile::~googleTile()
|
|
|
|
@ -40,10 +39,135 @@ void googleTile::ExportGeoPng(cv::Mat _pan, TileInfo info, std::string dir)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void googleTile::ExportTile(cv::Mat _pan, TileInfo panInfo, std::string dir,std::string fileString)
|
|
|
|
|
void googleTile::ExportTileSet(cv::Mat _pan, vector<TileInfo> taskTilesVec, std::string dir,std::string fileString)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
int panWidth = _pan.cols;
|
|
|
|
|
int panHeight = _pan.rows;
|
|
|
|
|
|
|
|
|
|
int zoom = taskTilesVec[0].ind.z;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < taskTilesVec.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
TileInfo tile = taskTilesVec[i];
|
|
|
|
|
|
|
|
|
|
TileBox tilebox = tile.boxLatLon;
|
|
|
|
|
|
|
|
|
|
RECT32S tileBoxInPan = tile.boxInPan;
|
|
|
|
|
|
|
|
|
|
int x1 = tileBoxInPan.x;
|
|
|
|
|
int x2 = tileBoxInPan.x + tileBoxInPan.w;
|
|
|
|
|
int y1 = tileBoxInPan.y;
|
|
|
|
|
int y2 = tileBoxInPan.y + tileBoxInPan.h;
|
|
|
|
|
|
|
|
|
|
// 有不完整瓦片,不保存
|
|
|
|
|
if (x1 < 0 || y1 < 0 || x2 > panWidth - 1 || y2 > panHeight - 1)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 确保坐标在图像范围内
|
|
|
|
|
x1 = std::max(0, std::min(x1, panWidth - 1));
|
|
|
|
|
y1 = std::max(0, std::min(y1, panHeight - 1));
|
|
|
|
|
x2 = std::max(0, std::min(x2, panWidth - 1));
|
|
|
|
|
y2 = std::max(0, std::min(y2, panHeight - 1));
|
|
|
|
|
|
|
|
|
|
// 提取瓦片
|
|
|
|
|
cv::Rect tileRect(x1, y1, x2 - x1, y2 - y1);
|
|
|
|
|
cv::Mat tileImg = _pan(tileRect);
|
|
|
|
|
|
|
|
|
|
// 标准web瓦片尺寸
|
|
|
|
|
if (tileImg.cols != 256 || tileImg.rows != 256)
|
|
|
|
|
{
|
|
|
|
|
cv::resize(tileImg, tileImg, cv::Size(256, 256));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 生成文件名
|
|
|
|
|
std::string tileDir = dir + "/" + std::to_string(zoom);
|
|
|
|
|
std::string fileName = tileDir + "/" + std::to_string(tile.ind.x) + "_" + std::to_string(tile.ind.y) + ".png";
|
|
|
|
|
// 创建目录
|
|
|
|
|
if (!fs::exists(tileDir))
|
|
|
|
|
{
|
|
|
|
|
fs::create_directories(tileDir);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 保存瓦片为图像文件
|
|
|
|
|
cv::imwrite(fileName, tileImg);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 输出KML
|
|
|
|
|
WriteKml(taskTilesVec,dir + "/" + fileString + "_z" + std::to_string(zoom) + ".kml");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void googleTile::ExportOneTile(cv::Mat _pan, TileInfo tile, std::string dir, std::string fileString)
|
|
|
|
|
{
|
|
|
|
|
int zoom = panInfo.ind.z;
|
|
|
|
|
TileBox panBox = panInfo.box;
|
|
|
|
|
|
|
|
|
|
int panWidth = _pan.cols;
|
|
|
|
|
int panHeight = _pan.rows;
|
|
|
|
|
int zoom = tile.ind.z;
|
|
|
|
|
|
|
|
|
|
TileBox tilebox = tile.boxLatLon;
|
|
|
|
|
|
|
|
|
|
RECT32S tileBoxInPan = tile.boxInPan;
|
|
|
|
|
|
|
|
|
|
int x1 = tileBoxInPan.x;
|
|
|
|
|
int x2 = tileBoxInPan.x + tileBoxInPan.w;
|
|
|
|
|
int y1 = tileBoxInPan.y;
|
|
|
|
|
int y2 = tileBoxInPan.y + tileBoxInPan.h;
|
|
|
|
|
|
|
|
|
|
// 有不完整瓦片,不保存
|
|
|
|
|
if (x1 < 0 || y1 < 0 || x2 > panWidth - 1 || y2 > panHeight - 1)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 确保坐标在图像范围内
|
|
|
|
|
x1 = std::max(0, std::min(x1, panWidth - 1));
|
|
|
|
|
y1 = std::max(0, std::min(y1, panHeight - 1));
|
|
|
|
|
x2 = std::max(0, std::min(x2, panWidth - 1));
|
|
|
|
|
y2 = std::max(0, std::min(y2, panHeight - 1));
|
|
|
|
|
|
|
|
|
|
// 提取瓦片
|
|
|
|
|
cv::Rect tileRect(x1, y1, x2 - x1, y2 - y1);
|
|
|
|
|
cv::Mat tileImg = _pan(tileRect);
|
|
|
|
|
|
|
|
|
|
// 标准web瓦片尺寸
|
|
|
|
|
if (tileImg.cols != 256 || tileImg.rows != 256)
|
|
|
|
|
{
|
|
|
|
|
cv::resize(tileImg, tileImg, cv::Size(256, 256));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 生成文件名
|
|
|
|
|
std::string tileDir = dir + "/" + std::to_string(zoom);
|
|
|
|
|
std::string fileName = tileDir + "/" + std::to_string(tile.ind.x) + "_" + std::to_string(tile.ind.y) + ".png";
|
|
|
|
|
std::string kmlPath = tileDir + "/" + std::to_string(tile.ind.x) + "_" + std::to_string(tile.ind.y) + ".kml";
|
|
|
|
|
|
|
|
|
|
tile.href = std::to_string(tile.ind.x) + "_" + std::to_string(tile.ind.y) + ".png";
|
|
|
|
|
|
|
|
|
|
// 创建目录
|
|
|
|
|
if (!fs::exists(tileDir))
|
|
|
|
|
{
|
|
|
|
|
fs::create_directories(tileDir);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 保存瓦片为图像文件
|
|
|
|
|
cv::imwrite(fileName, tileImg);
|
|
|
|
|
|
|
|
|
|
vector<TileInfo> info;
|
|
|
|
|
info.push_back(tile);
|
|
|
|
|
WriteKml(info, kmlPath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vector<TileInfo> googleTile::CalcTileOverlayVec(TileInfo areaInfo,int panWidth,int panHeight)
|
|
|
|
|
{
|
|
|
|
|
int zoom = areaInfo.ind.z;
|
|
|
|
|
TileBox panBox = areaInfo.boxLatLon;
|
|
|
|
|
|
|
|
|
|
// 计算四至的瓦片编号
|
|
|
|
|
TileIndex WN = LatLonToTile(panBox.north, panBox.west, zoom);
|
|
|
|
@ -57,8 +181,6 @@ void googleTile::ExportTile(cv::Mat _pan, TileInfo panInfo, std::string dir,std:
|
|
|
|
|
int yStart = EN.y;
|
|
|
|
|
int yEnd = ES.y;
|
|
|
|
|
|
|
|
|
|
int panWidth = _pan.cols;
|
|
|
|
|
int panHeight = _pan.rows;
|
|
|
|
|
|
|
|
|
|
vector<TileInfo> taskTiles;
|
|
|
|
|
|
|
|
|
@ -66,54 +188,32 @@ void googleTile::ExportTile(cv::Mat _pan, TileInfo panInfo, std::string dir,std:
|
|
|
|
|
{
|
|
|
|
|
for (size_t j = xStart; j < xEnd; j++)
|
|
|
|
|
{
|
|
|
|
|
TileIndex id = {j,i,zoom};
|
|
|
|
|
TileIndex id = { j,i,zoom };
|
|
|
|
|
TileBox tilebox = GetTileBox(id);
|
|
|
|
|
|
|
|
|
|
// 填充
|
|
|
|
|
TileInfo info = { 0 };
|
|
|
|
|
info.box = tilebox;
|
|
|
|
|
info.ind = id;
|
|
|
|
|
|
|
|
|
|
// 计算瓦片在全景图中的像素位置
|
|
|
|
|
int x1 = (tilebox.west - panBox.west) / (panBox.east - panBox.west) * panWidth;
|
|
|
|
|
int y1 = (panBox.north - tilebox.north) / (panBox.north - panBox.south) * panHeight;
|
|
|
|
|
int x2 = (tilebox.east - panBox.west) / (panBox.east - panBox.west) * panWidth;
|
|
|
|
|
int y2 = (panBox.north - tilebox.south) / (panBox.north - panBox.south) * panHeight;
|
|
|
|
|
|
|
|
|
|
// 有不完整瓦片,不保存
|
|
|
|
|
if (x1 < 0 || y1 < 0 || x2 > panWidth - 1 || y2 > panHeight - 1)
|
|
|
|
|
// 瓦片不完整覆盖则不输出
|
|
|
|
|
if (tilebox.west < panBox.west|| panBox.north < tilebox.north
|
|
|
|
|
|| tilebox.east > panBox.east || panBox.south > tilebox.south)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 确保坐标在图像范围内
|
|
|
|
|
x1 = std::max(0, std::min(x1, panWidth - 1));
|
|
|
|
|
y1 = std::max(0, std::min(y1, panHeight - 1));
|
|
|
|
|
x2 = std::max(0, std::min(x2, panWidth - 1));
|
|
|
|
|
y2 = std::max(0, std::min(y2, panHeight - 1));
|
|
|
|
|
|
|
|
|
|
// 提取瓦片
|
|
|
|
|
cv::Rect tileRect(x1, y1, x2 - x1, y2 - y1);
|
|
|
|
|
cv::Mat tile = _pan(tileRect);
|
|
|
|
|
|
|
|
|
|
// 标准web瓦片尺寸
|
|
|
|
|
// if (tile.cols != 256 || tile.rows != 256)
|
|
|
|
|
// {
|
|
|
|
|
// cv::resize(tile, tile, cv::Size(256, 256));
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// 生成文件名
|
|
|
|
|
std::string tileDir = dir + "/" + std::to_string(zoom);
|
|
|
|
|
std::string fileName = tileDir + "/" + std::to_string(j) + "_" + std::to_string(i) + ".png";
|
|
|
|
|
// 创建目录
|
|
|
|
|
if (!fs::exists(tileDir))
|
|
|
|
|
{
|
|
|
|
|
fs::create_directories(tileDir);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 保存瓦片为图像文件
|
|
|
|
|
cv::imwrite(fileName, tile);
|
|
|
|
|
// 计算瓦片在全景图中的像素位置
|
|
|
|
|
RECT32S rect = { 0 };
|
|
|
|
|
rect.x = (tilebox.west - panBox.west) / (panBox.east - panBox.west) * panWidth;
|
|
|
|
|
rect.y = (panBox.north - tilebox.north) / (panBox.north - panBox.south) * panHeight;
|
|
|
|
|
rect.w = (tilebox.east - panBox.west) / (panBox.east - panBox.west) * panWidth - rect.x;
|
|
|
|
|
rect.h = (panBox.north - tilebox.south) / (panBox.north - panBox.south) * panHeight - rect.y;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 填充
|
|
|
|
|
TileInfo info = { 0 };
|
|
|
|
|
info.boxLatLon = tilebox;
|
|
|
|
|
info.ind = id;
|
|
|
|
|
info.boxInPan = rect;
|
|
|
|
|
|
|
|
|
|
// 补充瓦片信息
|
|
|
|
|
info.tileName = std::to_string(j) + "_" + std::to_string(i) + "_" + std::to_string(zoom);
|
|
|
|
@ -123,16 +223,14 @@ void googleTile::ExportTile(cv::Mat _pan, TileInfo panInfo, std::string dir,std:
|
|
|
|
|
taskTiles.push_back(info);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 输出KML
|
|
|
|
|
WriteKml(taskTiles,dir + "/" + fileString + "_z" + std::to_string(zoom) + ".kml");
|
|
|
|
|
|
|
|
|
|
return taskTiles;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int googleTile::getZoomLevel(float mp)
|
|
|
|
|
int googleTile::ZoomLevel(float mp)
|
|
|
|
|
{
|
|
|
|
|
int nLev = 0;
|
|
|
|
|
// 计算单位瓦片的实际覆盖
|
|
|
|
@ -140,11 +238,12 @@ int googleTile::getZoomLevel(float mp)
|
|
|
|
|
|
|
|
|
|
int earthLen = 40075017;
|
|
|
|
|
|
|
|
|
|
nLev = std::floor(std::log2(earthLen / meters_cover));
|
|
|
|
|
nLev = std::floor(std::log2(earthLen / meters_cover)) + 1;
|
|
|
|
|
|
|
|
|
|
return nLev;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TileIndex googleTile::LatLonToTile(double latitude, double longitude, int zoomLevel)
|
|
|
|
|
{
|
|
|
|
|
// 将纬度转换为墨卡托投影
|
|
|
|
@ -206,10 +305,10 @@ void googleTile::WriteKml(vector<TileInfo> tiles, string filePath)
|
|
|
|
|
kml_file << " <href>" << tile.href << "</href>" << std::endl;
|
|
|
|
|
kml_file << " </Icon>" << std::endl;
|
|
|
|
|
kml_file << " <LatLonBox>" << std::endl;
|
|
|
|
|
kml_file << " <north>" << tile.box.north << "</north>" << std::endl;
|
|
|
|
|
kml_file << " <south>" << tile.box.south << "</south>" << std::endl;
|
|
|
|
|
kml_file << " <east>" << tile.box.east << "</east>" << std::endl;
|
|
|
|
|
kml_file << " <west>" << tile.box.west << "</west>" << std::endl;
|
|
|
|
|
kml_file << " <north>" << std::fixed << std::setprecision(6) << tile.boxLatLon.north << "</north>" << std::endl;
|
|
|
|
|
kml_file << " <south>" << std::fixed << std::setprecision(6) << tile.boxLatLon.south << "</south>" << std::endl;
|
|
|
|
|
kml_file << " <east>" << std::fixed << std::setprecision(6) << tile.boxLatLon.east << "</east>" << std::endl;
|
|
|
|
|
kml_file << " <west>" << std::fixed << std::setprecision(6) << tile.boxLatLon.west << "</west>" << std::endl;
|
|
|
|
|
kml_file << " </LatLonBox>" << std::endl;
|
|
|
|
|
kml_file << "</GroundOverlay>" << std::endl;
|
|
|
|
|
}
|
|
|
|
@ -223,6 +322,3 @@ void googleTile::WriteKml(vector<TileInfo> tiles, string filePath)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|