Angular中基于OpenLayers与ol-cesium搭建3D地图报错求助
迁移OpenLayers+Cesium+ol-cesium项目到Angular(替代CDN+解决导入报错)
一、安装依赖(替代CDN)
首先通过npm安装所有核心依赖及TypeScript类型定义,确保版本兼容(ol-cesium 2.x对应OpenLayers 6.x,与你原项目版本匹配):
npm install ol cesium ol-cesium npm install --save-dev @types/cesium @types/ol
二、配置Angular项目
1. 配置静态资源与样式(修改angular.json)
在projects -> 你的项目名 -> architect -> build -> options中添加以下配置,确保Cesium的静态资源(Widgets、Assets等)能被Angular正确打包:
"assets": [ "src/favicon.ico", "src/assets", { "glob": "**/*", "input": "node_modules/cesium/Build/Cesium", "output": "assets/cesium" } ], "styles": [ "src/styles.css", "node_modules/ol/ol.css", "node_modules/cesium/Build/Cesium/Widgets/widgets.css", "node_modules/ol-cesium/dist/olcesium.css" ]
2. 配置TypeScript类型(修改tsconfig.json)
在compilerOptions中添加Cesium和OpenLayers的类型引用,避免类型报错:
"compilerOptions": { // 保留原有配置... "types": ["cesium", "ol"], "paths": { "cesium": ["node_modules/cesium/Build/Cesium/Cesium.js"] } }
三、组件代码实现
1. 模板文件(app.component.html)
<div class="ol-ces-map" #mapContainer></div> <button class="switch-btn" (click)="toggle2D3D()">Switch 2D/3D</button>
2. 样式文件(app.component.css)
html, body, .ol-ces-map { height: 100%; width: 100%; padding: 0; margin: 0; } .switch-btn { position: absolute; top: 10px; right: 50px; z-index: 1000; padding: 4px; }
3. 逻辑文件(app.component.ts)
正确导入所有模块,避免报错:
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; import Map from 'ol/Map'; import View from 'ol/View'; import TileLayer from 'ol/layer/Tile'; import XYZ from 'ol/source/XYZ'; import { defaults as defaultControls } from 'ol/control'; import { fromLonLat } from 'ol/proj'; import OLCesium from 'olcs/OLCesium'; import * as Cesium from 'cesium'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { @ViewChild('mapContainer') mapContainer!: ElementRef<HTMLDivElement>; private map!: Map; private olCesium!: OLCesium; ngOnInit(): void { // 配置Cesium资源基础路径 (window as any).CESIUM_BASE_URL = '/assets/cesium'; // 可选:设置Cesium Ion Token(若使用Ion地形/资源需填写) Cesium.Ion.defaultAccessToken = '你的Ion Token'; // 初始化OpenLayers控件 const controls = defaultControls({ rotate: true, rotateOptions: { tipLabel: "Reset rotation. \nUse Alt+Shift+Drag to rotate the map." } }); // 地图中心点与缩放级别 const zoom = 3; const center = fromLonLat([-96.41778916767144, 39.90201978025539]); // 创建影像图层 const worldImagery = new TileLayer({ source: new XYZ({ url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', maxZoom: 19 }) }); worldImagery.set('name', 'tileLayer'); // 创建OpenLayers地图实例 this.map = new Map({ controls: controls, target: this.mapContainer.nativeElement, layers: [ worldImagery, new TileLayer({ extent: [-13884991, 2870341, -7455066, 6338219], }) ], view: new View({ center: center, zoom: zoom }) }); // 初始化OLCesium(关联OpenLayers地图) this.olCesium = new OLCesium({ map: this.map, sceneOptions: { mapProjection: new Cesium.WebMercatorProjection() } }); const scene = this.olCesium.getCesiumScene(); // 默认禁用3D模式 this.olCesium.setEnabled(false); // 开启地形深度测试 scene.globe.depthTestAgainstTerrain = true; } // 切换2D/3D模式 toggle2D3D(): void { this.olCesium.setEnabled(!this.olCesium.getEnabled()); } }
四、常见导入报错解决方案
找不到模块
olcs/OLCesium:- 检查
package.json中ol-cesium与ol的版本兼容性(ol-cesium 2.x需搭配ol 6.x); - 确保执行了
npm install,依赖已正确安装。
- 检查
TypeScript类型报错:
- 确认已安装
@types/cesium和@types/ol; - 检查
tsconfig.json的types数组是否包含cesium和ol。
- 确认已安装
Cesium资源加载失败:
- 验证
angular.json的assets配置是否正确,确保node_modules/cesium/Build/Cesium下的文件被复制到assets/cesium; - 确认
CESIUM_BASE_URL设置为/assets/cesium,路径与打包后的资源位置一致。
- 验证
内容的提问来源于stack exchange,提问作者Beginner
相关产品推荐
相关产品推荐

