diff --git a/src/app/TileBasemap.cpp b/src/app/TileBasemap.cpp index 8a12977..80abb94 100644 --- a/src/app/TileBasemap.cpp +++ b/src/app/TileBasemap.cpp @@ -49,8 +49,11 @@ constexpr double kPi = 3.14159265358979323846; constexpr double kEarthCirc = 40075016.686; // 赤道周长(米) = z0 单瓦片地面尺寸 constexpr double kTilesAcross = 4.0; // 视野跨度目标覆盖瓦片数(决定层级) -// 地面起伏:AWS Terrarium DEM 瓦片(免费/无 token,XYZ Web-Mercator 与卫星瓦片对齐)。 -// elev(米) = R*256 + G + B/256 - 32768。数据到约 z15,更高层级无 DEM → 保持平面。 +// 地面起伏:Mapbox terrain-RGB DEM 瓦片(原版 web 同款源,全球 CDN,比 AWS Terrarium 快)。 +// 公式 elev(米) = -10000 + (R*65536 + G*256 + B)*0.1。数据到 z15,更高层级取祖先块。 +// kMapboxToken:原版 commercial-admin 的 Mapbox 公开 token(pk.*,客户端用,同 天地图 tk 性质)。 +const char* kMapboxToken = + "pk.eyJ1IjoidGJ1c2FuIiwiYSI6ImNtZjY2emZneDBkY24ybXB4cmpvdmwzNWYifQ.h6tcQ380WN5AW6fZr08how"; constexpr int kDemMaxZoom = 15; constexpr int kTerrainGrid = 32; // 每瓦片网格分辨率(33x33 顶点) constexpr double kTerrainExag = 1.0; // 地形垂向夸张(1=真实高程) @@ -88,7 +91,7 @@ double demElev(const QImage& dem, double fx, double fy) { const int px = std::clamp(static_cast(std::lround(fx * (w - 1))), 0, w - 1); const int py = std::clamp(static_cast(std::lround(fy * (h - 1))), 0, h - 1); const QRgb c = dem.pixel(px, py); - return qRed(c) * 256.0 + qGreen(c) + qBlue(c) / 256.0 - 32768.0; + return -10000.0 + (qRed(c) * 65536.0 + qGreen(c) * 256.0 + qBlue(c)) * 0.1; // Mapbox terrain-RGB } } // namespace @@ -341,12 +344,13 @@ void TileBasemap::fetchTerrain(int z, int x, int y, long long key, vtkSmartPoint qInfo() << "[basemap] 首次拉DEM 卫星z=" << z << " → DEMz=" << dz << "(" << dx << "," << dy << ")"; } - // 必须 https:该 S3 桶对纯 http 返回 403(实测)。 + // Mapbox terrain-RGB(pngraw 无损,保证高程解码准确);原版同源,全球 CDN。 const QString url = - QStringLiteral("https://s3.amazonaws.com/elevation-tiles-prod/terrarium/%1/%2/%3.png") + QStringLiteral("https://api.mapbox.com/v4/mapbox.terrain-rgb/%1/%2/%3.pngraw?access_token=%4") .arg(dz) .arg(dx) - .arg(dy); + .arg(dy) + .arg(QString::fromLatin1(kMapboxToken)); const int gen = generation_; QNetworkReply* reply = nam_.get(QNetworkRequest(QUrl(url))); connect(reply, &QNetworkReply::finished, this, [this, reply, key, demKey, gen, place]() {