Skip to content

3D模式

SDK 支持 3D 地球模式(Globe),可以将地图从平面投影切换为球面投影,提供更真实的地球视觉效果。

启用3D模式

设置投影类型

javascript
// 启用3D地球模式
sdk.map.setProjection({
  type: "globe",
});

// 切换回平面模式
sdk.map.setProjection({
  type: "", // 空字符串表示默认平面投影
});

初始化时设置

javascript
const sdk = new navMap.MapSDK({
  container: "map",
  center: [116.39, 39.9],
  zoom: 10,
  // 注意:投影类型需要在样式加载后设置
});

sdk.on("load", () => {
  // 在样式加载后设置3D模式
  sdk.map.setProjection({
    type: "globe",
  });
});

3D效果配置

设置天空和大气效果

javascript
sdk.on("load", () => {
  // 设置天空颜色
  sdk.setSky({
    "sky-color": "#0C2E4B",        // 天空颜色
    "horizon-color": "#09112F",     // 地平线颜色
    "fog-color": "#09112F",         // 雾颜色
    "fog-ground-blend": 0.5,       // 地面雾混合度
    "horizon-fog-blend": 0.1,       // 地平线雾混合度
    "sky-horizon-blend": 1.0,       // 天空地平线混合度
    "atmosphere-blend": 0.5,       // 大气混合度
  });
});

设置倾斜角度

javascript
// 设置地图倾斜角度(0-60度)
sdk.setPitch(60);

// 带动画效果
sdk.flyTo({
  pitch: 60,
  duration: 2000,
});

设置旋转角度

javascript
// 设置地图旋转角度(0-360度)
sdk.setBearing(45);

// 带动画效果
sdk.flyTo({
  bearing: 45,
  duration: 2000,
});

3D模式切换

创建切换按钮

html
<button id="toggle-3d">切换3D模式</button>
javascript
let is3DMode = false;

document.getElementById("toggle-3d").addEventListener("click", () => {
  is3DMode = !is3DMode;
  
  if (is3DMode) {
    // 切换到3D模式
    sdk.map.setProjection({
      type: "globe",
    });
    
    // 设置3D效果
    sdk.setSky({
      "sky-color": "#0C2E4B",
      "horizon-color": "#09112F",
      "fog-color": "#09112F",
    });
    
    // 设置倾斜角度
    sdk.flyTo({
      pitch: 60,
      duration: 1000,
    });
  } else {
    // 切换回平面模式
    sdk.map.setProjection({
      type: "",
    });
    
    // 重置倾斜角度
    sdk.flyTo({
      pitch: 0,
      duration: 1000,
    });
  }
});

3D模式下的交互

旋转控制

在3D模式下,可以通过拖拽来旋转地球:

javascript
// 启用旋转(默认启用)
sdk.dragRotate.enable();

// 禁用旋转
sdk.dragRotate.disable();

倾斜控制

javascript
// 右键拖拽可以倾斜地图
// 或使用代码控制
sdk.flyTo({
  pitch: 60,
  duration: 1000,
});

缩放控制

javascript
// 3D模式下缩放仍然有效
sdk.on("zoom", () => {
  console.log("当前缩放级别:", sdk.getZoom());
});

3D模式示例

完整示例

javascript
let sdk;
let is3DMode = false;

async function initMap() {
  sdk = new navMap.MapSDK({
    container: "map",
    center: [116.39, 39.9],
    zoom: 3, // 3D模式建议使用较小的初始缩放级别
  });

  sdk.on("load", () => {
    setup3DMode();
  });
}

function setup3DMode() {
  // 默认启用3D模式
  enable3DMode();
  
  // 设置天空效果
  sdk.setSky({
    "sky-color": "#0C2E4B",
    "horizon-color": "#09112F",
    "fog-color": "#09112F",
    "fog-ground-blend": 0.5,
    "horizon-fog-blend": 0.1,
    "sky-horizon-blend": 1.0,
    "atmosphere-blend": 0.5,
  });
  
  // 设置初始倾斜角度
  sdk.setPitch(45);
  
  // 切换按钮
  document.getElementById("toggle-3d").addEventListener("click", () => {
    if (is3DMode) {
      disable3DMode();
    } else {
      enable3DMode();
    }
  });
}

function enable3DMode() {
  is3DMode = true;
  sdk.map.setProjection({
    type: "globe",
  });
  
  sdk.flyTo({
    pitch: 60,
    bearing: 0,
    duration: 1000,
  });
}

function disable3DMode() {
  is3DMode = false;
  sdk.map.setProjection({
    type: "",
  });
  
  sdk.flyTo({
    pitch: 0,
    bearing: 0,
    duration: 1000,
  });
}

initMap();

自动旋转地球

javascript
let rotationInterval;

function startAutoRotation() {
  let bearing = 0;
  
  rotationInterval = setInterval(() => {
    bearing += 0.5; // 每次增加0.5度
    if (bearing >= 360) bearing = 0;
    
    sdk.setBearing(bearing);
  }, 50); // 每50ms更新一次
}

function stopAutoRotation() {
  if (rotationInterval) {
    clearInterval(rotationInterval);
    rotationInterval = null;
  }
}

// 开始自动旋转
startAutoRotation();

// 停止自动旋转
stopAutoRotation();

性能优化

3D模式下的性能考虑

  1. 缩放级别:3D模式在低缩放级别(2-5)下效果最佳
  2. 图层简化:在3D模式下可以隐藏一些细节图层以提高性能
  3. 动画优化:使用 essential: true 选项在低性能设备上跳过动画
javascript
sdk.on("load", () => {
  // 启用3D模式
  sdk.map.setProjection({
    type: "globe",
  });
  
  // 根据缩放级别调整图层
  sdk.on("zoom", () => {
    const zoom = sdk.getZoom();
    
    if (zoom < 5) {
      // 低缩放级别:隐藏详细图层
      sdk.hideLayers(["detail-layer"]);
    } else {
      // 高缩放级别:显示详细图层
      sdk.showLayers(["detail-layer"]);
    }
  });
});

注意事项

  1. 投影设置时机:必须在样式加载(load 事件)后设置投影类型
  2. 浏览器兼容性:3D模式需要支持 WebGL 的现代浏览器
  3. 性能影响:3D模式可能比平面模式消耗更多资源
  4. 缩放级别:3D模式在低缩放级别下效果更明显
  5. 样式兼容性:某些样式可能在3D模式下显示效果不同

常见问题

Q: 如何检测当前是否为3D模式?

javascript
function is3DMode() {
  const projection = sdk.map.getProjection();
  return projection && projection.type === "globe";
}

Q: 如何在3D模式下保持特定区域居中?

javascript
// 使用 flyTo 方法,SDK 会自动处理3D投影
sdk.flyTo({
  center: [116.39, 39.9],
  zoom: 10,
  pitch: 60,
  bearing: 0,
  duration: 2000,
});

Q: 3D模式下如何优化性能?

javascript
// 1. 降低图层复杂度
sdk.on("zoom", () => {
  if (sdk.getZoom() < 8) {
    sdk.hideLayers(["complex-layer"]);
  }
});

// 2. 使用 LOD(细节层次)配置
sdk.layerManager.setLODEnabled(true);

// 3. 减少动画时长
sdk.flyTo({
  pitch: 60,
  duration: 500, // 较短的动画时长
  essential: true, // 在低性能设备上跳过
});