#include "googleTile.h" #include #include #include #include #include #include using std::string; googleTile::googleTile() { } googleTile::~googleTile() { } void googleTile::ExportGeoPng(cv::Mat _pan, TileInfo info, std::string dir, std::string name) { // 保存全景图 string png_path = dir + "/" + name + ".png"; cv::imwrite(png_path, _pan); // 写入kml string kml_path = dir + "/" + name + ".kml"; std::ofstream kml_file(kml_path); // 写入 KML 文件的头部 kml_file << "" << std::endl; kml_file << "" << std::endl; kml_file << "" << std::endl; // 写入 GroundOverlay 元素 kml_file << "" << std::endl; kml_file << " My Panoramic Image" << std::endl; kml_file << " " << std::endl; kml_file << " " << name + ".png" << "" << std::endl; kml_file << " " << std::endl; // 使用四个角点计算 LatLonBox kml_file << " " << std::endl; kml_file << " " << info.north << "" << std::endl; // 经度范围 kml_file << " " << info.south << "" << std::endl; kml_file << " " << info.east << "" << std::endl; // 纬度范围 kml_file << " " << info.west << "" << std::endl; kml_file << " " << std::endl; // 写入 KML 文件的尾部 kml_file << "" << std::endl; kml_file << "" << std::endl; kml_file << "" << std::endl; kml_file.close(); } void googleTile::ExportTile(cv::Mat _pan, TileInfo info, std::string dir, std::string name) { } cv::Point2f googleTile::latLonToGlobal(double lat, double lon) { double tileSize = 256.0; double n = std::pow(2.0, zoom_); double x = (lon + 180.0) / 360.0 * tileSize * n; double latRad = lat * CV_PI / 180.0; double y = (1 - std::log(std::tan(latRad) + 1 / std::cos(latRad)) / CV_PI) / 2 * tileSize * n; return cv::Point2f(static_cast(x), static_cast(y)); } std::pair googleTile::globalToLatLon(const cv::Point2f& pt) { double tileSize = 256.0; double n = std::pow(2.0, zoom_); double lon = pt.x / (tileSize * n) * 360.0 - 180.0; double latRad = std::atan(std::sinh(CV_PI * (1 - 2 * pt.y / (tileSize * n)))); double lat = latRad * 180.0 / CV_PI; return std::make_pair(lat, lon); } cv::Mat googleTile::computeHomography() { std::vector srcPts; std::vector dstPts; for (const auto& corner : geoCorners_) { srcPts.push_back(latLonToGlobal(corner.first, corner.second)); } dstPts.push_back(cv::Point2f(0.0f, 0.0f)); dstPts.push_back(cv::Point2f(static_cast(image_.cols), 0.0f)); dstPts.push_back(cv::Point2f(static_cast(image_.cols), static_cast(image_.rows))); dstPts.push_back(cv::Point2f(0.0f, static_cast(image_.rows))); return cv::getPerspectiveTransform(srcPts, dstPts); } void googleTile::generateTiles() { //std::filesystem::create_directories(outputDir_); //cv::Mat H = computeHomography(); //std::vector globalCorners; //for (const auto& corner : geoCorners_) //{ // globalCorners.push_back(latLonToGlobal(corner.first, corner.second)); //} //float minX = globalCorners[0].x, maxX = globalCorners[0].x; //float minY = globalCorners[0].y, maxY = globalCorners[0].y; //for (const auto& p : globalCorners) //{ // minX = std::min(minX, p.x); // maxX = std::max(maxX, p.x); // minY = std::min(minY, p.y); // maxY = std::max(maxY, p.y); //} //int tileSize = 256; //int xTileMin = static_cast(std::floor(minX / tileSize)); //int xTileMax = static_cast(std::floor(maxX / tileSize)); //int yTileMin = static_cast(std::floor(minY / tileSize)); //int yTileMax = static_cast(std::floor(maxY / tileSize)); //std::vector tileInfos; //for (int tx = xTileMin; tx <= xTileMax; tx++) //{ // for (int ty = yTileMin; ty <= yTileMax; ty++) // { // std::vector tileGlobalPts = { // {cv::Point2f(tx * tileSize, ty * tileSize)}, // {cv::Point2f((tx + 1) * tileSize, ty * tileSize)}, // {cv::Point2f((tx + 1) * tileSize, (ty + 1) * tileSize)}, // {cv::Point2f(tx * tileSize, (ty + 1) * tileSize)} }; // std::vector tileImgPts; // cv::perspectiveTransform(tileGlobalPts, tileImgPts, H); // //cv::Mat tileTransform = cv::getPerspectiveTransform(tileImgPts, { // // {0, 0}, {tileSize, 0}, {tileSize, tileSize}, {0, tileSize} }); // cv::Mat tileImg; // //cv::warpPerspective(image_, tileImg, tileTransform, cv::Size(tileSize, tileSize)); // std::string tileDir = outputDir_ + "/" + std::to_string(zoom_) + "/" + std::to_string(tx); // std::filesystem::create_directories(tileDir); // std::string tilePath = tileDir + "/" + std::to_string(ty) + ".png"; // cv::imwrite(tilePath, tileImg); // tileInfos.push_back({ tx, ty, globalToLatLon({cv::Point2f(tx * tileSize, ty * tileSize)}).first, // globalToLatLon({cv::Point2f((tx + 1) * tileSize, (ty + 1) * tileSize)}).first, // globalToLatLon({cv::Point2f((tx + 1) * tileSize, (ty + 1) * tileSize)}).second, // globalToLatLon({cv::Point2f(tx * tileSize, ty * tileSize)}).second }); // } //} //generateKML(tileInfos); }