ワンクリックで
minemap-terrain-and-analysis
MineMap 地形设置(setTerrain)、DEM 高程查询、地形分析、TerrainLeveling、相机碰撞高度与 terrain 相关约束。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
MineMap 地形设置(setTerrain)、DEM 高程查询、地形分析、TerrainLeveling、相机碰撞高度与 terrain 相关约束。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
MineMap 3D 公告板(Billboard)专题。覆盖 BillboardMaterial / BillboardGeometry / BillboardInstance 动画、拾取高亮、动态纹理更新与轨迹对象联动;不与 DOM 覆盖物 Marker 混淆。
MineMap 云与大气渲染链。用于启用体积云(多层 CloudLayer)、单片实例化云(map.cloudCollection)、大气散射与太阳 / 天空辐照度,重点说明主分支公开参数与禁用字段。
MineMap 事件订阅模型、图层事件代理、once/off 管理、矢量与三维对象拾取。
MineMap 热力图(heatmap)专题。用于二维 / 三维热力图、贴地热力、聚合权重、热力色阶与 3D 显示模式,重点说明 paint/layout 参数边界与典型失败场景。
MineMap KML 数据源。用于加载 KML / KMZ 文件,解析 LineStyle / IconStyle / LabelStyle / PolyStyle 等样式继承,并把 KML 属性映射为 line / circle / fill / symbol 派生图层。
MineMap 材质与着色规范。覆盖 `StandardMaterial`、`PhongMaterial`、`PhysicalMaterial`、`LambertMaterial`、`PolylineMaterial` 等主流材质的选型与调参。
| name | minemap-terrain-and-analysis |
| description | MineMap 地形设置(setTerrain)、DEM 高程查询、地形分析、TerrainLeveling、相机碰撞高度与 terrain 相关约束。 |
const map = new minemap.Map({
container: "map",
style,
position: [89.11, 27.4, 15000],
pitch: 55,
projection: minemap.ProjectionType.MERCATOR,
minHeightToDemSurface: 5,
terrainSkirtHeight: -1
});
map.on("load", () => {
map.setTerrain({
tiles: ["https://example.com/dem/{z}/{r}/{c}/{z}_{x}_{y}.terrain"],
availabilities: ["https://example.com/dem/layer.json"],
tileSize: 512,
maxzoom: 14,
extensions: {
requestVertexNormals: false,
requestWaterMask: false,
requestHeightFieldNormals: false
}
});
map.addSource("imagery", {
type: "raster",
tiles: ["https://example.com/satellite/{z}/{r}/{c}/{z}_{x}_{y}.jpg"],
tileSize: 512
});
map.addLayer({
id: "imagery",
type: "raster",
source: "imagery"
});
const height = map.queryDEMHeightByLngLat([89.11316, 27.40665]);
console.log(height.z);
});
map.setTerrain(...) 的本质不是“再叠一层 DEM 图层”。
它做的是:
所以要记住:
raster source/layermap.setTerrain() 管这就是为什么 MineMap 4.x 已不推荐继续用旧式 terrainTiles + renderWithTerrain 那套 source/layer 写法。
setTerrain() 背后实际做了什么map.setTerrain(options) 是 MineMap 4.x 推荐 DEM 接口。
源码里能确认的实际行为有:
symbolHeightExtraction 缓存style.rasterSourceCache.setTerrain(options) 切换 terrain sourceproxySourceCache 的 layer order,保证矢量贴地缓存状态刷新所以正确理解是:
setTerrain() 是一个全局场景切换动作TerrainTileSource 是内部 terrain 数据源。
从源码可确认:
quantizedheightmap_terrainTiles_tempTerrainTiles,用来减轻切换时闪烁maxzoom 时,不再继续请求更细 DEM,而是走上采样 upsample这决定了两个开发结论:
maxzoom 不是越大越好,取决于你实际 DEM 精度只开 setTerrain() 还不够,它只负责地表几何。
通常你还需要再加一个普通影像或栅格底图:
典型组合:
map.setTerrain(...)map.addSource("imagery", { type: "raster", ... })map.addLayer({ type: "raster", source: "imagery" })地形开启后,只是让地图有真实起伏。
要不要贴地,还要看对象本身:
adaptTerrainMarker / Popup 要看 setAltitude() 与 terrain pick不要把“开启 terrain”误解成“所有对象自动贴地完成”。
setTerrain() Parameter Surfacetiles: string[] | nulltileSize: numbermaxzoom: numberavailabilities: string[] | nullextensionstilesterrain 瓦片 URL 模板。
常见形式是 .terrain 文件:
tiles: ["https://example.com/dem/{z}/{r}/{c}/{z}_{x}_{y}.terrain"];
语义:
tiles: null 表示回退到平面/椭球地表源码实现上,传 falsy 也会退回 ellipsoid;但稳定文档写法仍建议显式用:
map.setTerrain({ tiles: null });
tileSizeDEM 瓦片大小。
MineMap 4.x terrain 相关示例和源码默认使用:
512建议:
512 组织maxzoomDEM 数据的最高请求层级。
源码注释明确给出了经验值:
1416注意:
availabilities,源码注释说明 maxzoom 不再是最高精度遍历的主要依据availabilities地形索引文件列表,常见是 layer.json。
它的价值很大:
queryAccurateDEMHeightByPoint() 想拿到“最高精度”结果时,推荐配置它maxzoom推荐:
layer.json,就加上extensionsterrain 扩展对象,源码里可确认的 3 个字段:
requestVertexNormalsrequestWaterMaskrequestHeightFieldNormals默认都为 false。
requestVertexNormals请求顶点法线扩展。
适用:
requestWaterMask请求水面掩膜扩展。
适用:
requestHeightFieldNormals请求区域场法线扩展。
这个在地形分析里尤其有意义。源码和 demo 都表明:
zeroTileRequestUrl这是一个非常值得写进 skill 的“半隐藏参数”。
虽然 map.setTerrain() 的当前类型注释里没有完整展开,但:
queryAccurateDEMHeightByPoint() 的示例里出现了它TerrainTileSource 构造函数里也明确支持它作用:
适合:
terrainSkirtHeight地图构造参数和运行时属性都支持它。
语义:
规则:
< 0:按级别动态计算>= 0:固定值源码里动态值的实际逻辑是:
getLevelMaximumGeometricError(z) * 5.0建议:
-1运行时也可直接改:
map.terrainSkirtHeight = 80;
改完会重新按当前 terrain 配置刷新 terrain source。
minHeightToDemSurface这个参数非常关键,但经常被忽略。
语义:
默认值:
5适用:
运行时可直接调:
map.minHeightToDemSurface = 5;
enableUnderGround地下模式。注意:enableUnderGround 在主分支上是一个属性赋值,不是方法,调用方式与 enableLight / enableClouds 不同。
来源:source/api/map.js line 4999+。
两种开启方式:
// 方式 A:构造选项(推荐一次性开启)
var map = new minemap.Map({
container: "map",
style,
enableUnderGround: true, // 地下模式
position: [108.96, 34.21, 338],
pitch: 90,
maxZoom: 100, // 地下模式要尽量大于 24
logDepth: true // 必须配 logDepth
});
// 方式 B:运行时动态切换
map.enableUnderGround = true; // 开启
map.enableUnderGround = false; // 关闭
开启后行为:
raster / 影像)继续渲染,需要显式关闭 depth-test 避免被地形遮挡配套设置:
| 配套项 | 推荐值 | 说明 |
|---|---|---|
logDepth | true | 源码注释:否则进入地下后地形会闪烁(z-fighting) |
maxZoom | >= 24 | 地下模式要求 maxZoom 至少大于 24,否则可能报错 |
pitch | >= 80 | 高俯仰角更利于观察地下场景 |
raster depth-test | false | 影像层在地下时需关闭深度测试,否则会被地形遮住 |
示例(参考 demo/html/Underground.html):
var map = new minemap.Map({
container: "map",
style,
position: [108.96, 34.21, 338],
bearing: 90,
pitch: 90,
roll: 0,
maxZoom: 100,
minZoom: 1,
projection: "MERCATOR",
logDepth: true,
enableUnderGround: true
});
map.enableLight();
map.setTerrain({
tiles: ["https://.../dem/{z}/{r}/{c}/{z}_{x}_{y}.terrain"],
tileSize: 512,
maxzoom: 14
});
map.on("load", function () {
map.addSource("IMAGERY_SOURCE", {
type: "raster",
tiles: ["https://.../satellite/{z}/{r}/{c}/{z}_{x}_{y}.jpg"],
tileSize: 512
});
map.addLayer({
id: "IMAGERY",
type: "raster",
source: "IMAGERY_SOURCE",
minzoom: 0,
maxzoom: 23,
"depth-test": false, // 地下时影像不能被地形挡住
paint: { "raster-opacity": 1 }
});
// 地下管廊 / 隧道 / 设施
map.addSceneComponent({
id: "pipeline",
type: "3d-model",
data: "../data/UndergroundTube/pipeline.gltf",
modelFolder: "../data/UndergroundTube/",
rotation: [90, 0, 0],
position: [108.965, 34.218, 360] // z 大于 0 仍然显示为"在地下"
});
});
注意事项:
enableUnderGround 是属性赋值,不是 enableUnderGround() 方法调用;map.enableUnderGround() 会报错position 第三项(z/alt)填负值也可以工作,但源码注释提醒:未开启 enableUnderGround 时传负高度,会被定位到 [0, 0, 6378137*6]Sky 自动隐藏,相机飞到地下不会渲染天空盒适用场景:
requestInterval地图构造参数中的请求重试/等待间隔,源码注释明确写了:
60适用:
常见查询:
queryDEMHeightByPoint(...)queryAccurateDEMHeightByPoint(...)queryDEMHeightByLngLat(...)queryDEMSourceHeightByPoint(...)使用建议:地图稳定后(idle)再做高频批量查询。
queryDEMHeightByPoint(queryGeometry)输入:
过程:
sampleTerrain(...) 采样高程返回:
Vector3特点:
适合:
queryAccurateDEMHeightByPoint(queryGeometry)输入仍然是屏幕像素坐标,但内部会调用:
sampleTerrainMostDetailed(...)特点:
availabilities适合:
queryDEMHeightByLngLat(lnglat)输入:
输出:
Vector3适合:
queryDEMSourceHeightByPoint(e, source)这是更低层的“指定 DEM source”查询入口。
当前项目里更常用的还是前三个方法;只有你明确在做 DEM source 级控制时再使用它。
map.on("load", () => {
map.setTerrain({
tiles: [terrainUrl],
tileSize: 512,
maxzoom: 14
});
map.addSource("imagery", {
type: "raster",
tiles: [imageryUrl],
tileSize: 512
});
map.addLayer({
id: "imagery",
type: "raster",
source: "imagery"
});
});
这是最标准的 terrain 起图模式。
map.on("click", async (e) => {
const point = await map.queryAccurateDEMHeightByPoint(e.point);
console.log(point.z);
});
前提:
availabilitiesconst point = map.queryDEMHeightByLngLat([116.39, 39.9]);
const z = point.z;
适合在放模型、marker、分析点之前先拿地表高度。
terrain 打开后,Marker 拖拽会走 terrain pick。
这意味着:
适合:
terrain 开启后,如果 primitive 本身支持:
adaptTerrain: true就可以让线面对象沿地表起伏。
但这依赖对象本身的 geometry/material 支持,不是 terrain 自动替你完成的。
map.setTerrainAnalysis(options) 是 terrain 栅格分析入口。
当前源码可确认:
property 支持 SLOPE、ASPECT、ELEVATIONtype 支持 EXPONENTIAL、INTERVAL、CATEGORICALbasestopsdefaultregionhasArrowproperty决定分析的地形属性:
SLOPE:坡度ASPECT:坡向ELEVATION:高程带type颜色插值方式:
EXPONENTIALINTERVALCATEGORICAL如果用 EXPONENTIAL,可再配:
base默认 base = 1.0,也就是线性插值感。
stops分析值到颜色的映射表。
要求:
Color 名称default不命中 stops 时的默认颜色。
region区域分析时的掩膜区域。
不传时:
传入时:
hasArrow是否显示方向箭头。
源码注释写的是“目前仅有坡度分析有效”,而 demo 用它表达坡向指示,所以更稳妥的理解是:
map.setTerrainAnalysis({
type: minemap.InterpolationType.EXPONENTIAL,
property: minemap.TerrainAnalysisType.SLOPE,
stops: [
[0, "#00FF00"],
[30, "#FFFF66"],
[60, "#FF8000"],
[90, "#FF0000"]
],
default: "rgba(0,0,255,1)",
region: region,
hasArrow: true
});
TerrainLeveling:地形平整TerrainLeveling 不是简单的“盖一个面”。
从源码看,它会:
region 和平整深度 depthonAdd(map) 时找出与区域相交的 terrain tilecartographicListreferenceHeight也就是说,它本质是:
region: number[]:[lng, lat, lng, lat, ...]depth: number它是 scene object,不是 layer,也不是普通 analysis API。
推荐写法:
const leveling = new minemap.TerrainLeveling({
region: [89.1, 27.4, 89.2, 27.4, 89.2, 27.3, 89.1, 27.3],
depth: 50
});
map.addSceneComponent(leveling);
运行时可调:
leveling.setDepth(80);
console.warn 并禁用map.analysis 下默认挂载:
cutFillCollectionexcavationCollectionhighlightCollectionsightlineCollectionviewDomeCollectionviewshed3DCollectioninterferenceCollectionshadowAnalysisCollectionfloodAnalysisCollectionfloodAnalysisOfflineCollectionindex.js 已导出的其他分析类除了可视域、通视、淹没、阴影,公开导出里还包括:
HighlightCutFillExcavationViewDomeInterferenceInterferenceConjoinedProfilePlayer当前空间分析相关能力已按职责拆成 4 个 skill,不再只放在一个总包里:
minemap-terrain-and-analysis
map.analysis 容器入口minemap-business-visibility-analysis
Viewshed3DSightlineminemap-business-flood-and-shadow
FloodAnalysisFloodAnalysisOfflineShadowAnalysisminemap-business-measurement
Measurement3Dminemap-business-spatial-analysis-suite
setTerrainAnalysis(...)CutFillExcavationLimitHeightViewDomeInterferenceInterferenceConjoinedProfile文档策略:
Viewshed3D、Sightline、FloodAnalysis)切换项目/场景时统一 removeAll(),避免分析对象残留。
Highlight / CutFill / Excavation 更偏地形或对象表达修饰ViewDome / Interference / InterferenceConjoined 更偏视场与干扰表达Profile / Player 更偏剖切、播放或过程辅助推荐做法:按业务模块维护自己的分析对象引用,并同步挂入 map.analysis.*Collection,不要创建后失去控制句柄。
if (map.isTerrain()) {
console.log("terrain enabled");
}
map.setTerrain({ tiles: null });
虽然实现层面对 falsy 也有兼容,但文档化写法推荐保持显式。
queryDEMHeightByPoint() 而不是总是走 queryAccurateDEMHeightByPoint()availabilities 能配就配,尤其是高精度查询和大范围分析terrainSkirtHeight 优先保留动态值,除非你明确在调接缝问题TerrainLeveling 依赖 WebGL2,不要把它当成所有终端都能稳定开启的通用效果terrain 相关资料建议交叉看:
https://minedata.cn/https://minedata.cn/nce-support/guide-3D-Ultrahttps://minedata.cn/nce-support/api-3D-Ultrahttps://minedata.cn/nce-support/demoCenter-3D-Ultra本地 demo 里和 terrain 强相关的证据源包括:
demo/html/QueryDEMHeight.htmldemo/html/DemAnalysis.htmldemo/html/TerrainLeveling.htmldemo/html/MarkerDraggableOnTerrain.htmldemo/html/RasterTerrainChange.html查 terrain 时推荐顺序:
source/api/map.js、source/data-source/source-cache/TerrainTileSource.js 看真实行为minemap-official-resources-and-onboardingminemap-fundamentalsminemap-2d-3d-overlay-and-classificationminemap-marker-and-popupminemap-primitives-and-materialsminemap-business-visibility-analysisminemap-business-flood-and-shadowminemap-business-measurementminemap-business-spatial-analysis-suiteminemap-performance-and-backend