### 在 Vue 项目中使用 OpenLayers 加载天地图并实现轨迹回显与自动聚焦功能
在 Vue 项目中集成 OpenLayers 并加载天地图,可以按照以下方法实现轨迹回放和自动聚焦到轨迹位置的功能。
#### 1. 安装依赖
首先需要安装 Vue CLI 和 OpenLayers:
```bash
cnpm install -g @vue/cli
vue create vue-openlayers
cd vue-openlayers
cnpm install ol -S
```
#### 2. 引入天地图服务
天地图提供了多个图层服务(如矢量图层、影像图层等),可以通过 URL 请求获取。以下是引入天地图的代码示例[^1]:
```javascript
import 'ol/ol.css';
import { Map, View } from 'ol';
import TileLayer from 'ol/layer/Tile';
import XYZ from 'ol/source/XYZ';
const tiandituKey = 'your-tianditu-api-key'; // 替换为你的天地图 API Key
// 添加天地图矢量图层
const vectorLayer = new TileLayer({
source: new XYZ({
url: `https://t0.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=${tiandituKey}`,
}),
});
// 添加天地图注记图层
const annotationLayer = new TileLayer({
source: new XYZ({
url: `https://t0.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=${tiandituKey}`,
}),
});
// 创建地图实例
const map = new Map({
target: 'map',
layers: [vectorLayer, annotationLayer],
view: new View({
center: [0, 0],
zoom: 2,
}),
});
```
#### 3. 实现轨迹回放功能
OpenLayers 提供了 `ol.animation` 模块来实现动画效果。以下是一个简单的轨迹回放实现[^2]:
```javascript
import Feature from 'ol/Feature';
import Point from 'ol/geom/Point';
import VectorSource from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';
import Style from 'ol/style/Style';
import Icon from 'ol/style/Icon';
import { animate } from 'ol';
// 轨迹点数据 (示例)
const trackPoints = [
[116.4074, 39.9042], // 经纬度坐标
[116.4075, 39.9043],
[116.4076, 39.9044],
];
// 创建轨迹点
const trackFeatures = trackPoints.map((point) => {
return new Feature({
geometry: new Point([point[0] * 1e6, point[1] * 1e6]),
});
});
// 添加轨迹点到地图
const trackSource = new VectorSource({
features: trackFeatures,
});
const trackLayer = new VectorLayer({
source: trackSource,
style: new Style({
image: new Icon({
src: 'https://openlayers.org/en/v6.5.0/examples/data/icon.png',
}),
}),
});
map.addLayer(trackLayer);
// 实现轨迹回放
let index = 0;
function replayTrack() {
if (index >= trackFeatures.length) {
index = 0; // 循环播放
}
const feature = trackFeatures[index];
const coordinate = feature.getGeometry().getCoordinates();
map.getView().animate({
center: coordinate,
duration: 1000,
});
index++;
setTimeout(replayTrack, 1000); // 每秒更新一次位置
}
replayTrack();
```
#### 4. 自动聚焦到轨迹位置
通过设置地图视图的 `center` 和 `zoom` 属性,可以实现自动聚焦到轨迹位置。以下是一个示例:
```javascript
// 计算轨迹范围
const extent = trackSource.getExtent();
// 设置地图视图聚焦到轨迹范围
map.getView().fit(extent, {
padding: [50, 50, 50, 50],
duration: 1000,
});
```
#### 5. 完整代码示例
将上述代码整合到一个 Vue 组件中:
```vue
<template>
<div id="map" style="width: 100%; height: 100vh;"></div>
</template>
<script>
import 'ol/ol.css';
import { Map, View } from 'ol';
import TileLayer from 'ol/layer/Tile';
import XYZ from 'ol/source/XYZ';
import Feature from 'ol/Feature';
import Point from 'ol/geom/Point';
import VectorSource from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';
import Style from 'ol/style/Style';
import Icon from 'ol/style/Icon';
import { animate } from 'ol';
export default {
mounted() {
const tiandituKey = 'your-tianditu-api-key'; // 替换为你的天地图 API Key
const vectorLayer = new TileLayer({
source: new XYZ({
url: `https://t0.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=${tiandituKey}`,
}),
});
const annotationLayer = new TileLayer({
source: new XYZ({
url: `https://t0.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=${tiandituKey}`,
}),
});
const map = new Map({
target: 'map',
layers: [vectorLayer, annotationLayer],
view: new View({
center: [0, 0],
zoom: 2,
}),
});
const trackPoints = [
[116.4074, 39.9042],
[116.4075, 39.9043],
[116.4076, 39.9044],
];
const trackFeatures = trackPoints.map((point) => {
return new Feature({
geometry: new Point([point[0] * 1e6, point[1] * 1e6]),
});
});
const trackSource = new VectorSource({
features: trackFeatures,
});
const trackLayer = new VectorLayer({
source: trackSource,
style: new Style({
image: new Icon({
src: 'https://openlayers.org/en/v6.5.0/examples/data/icon.png',
}),
}),
});
map.addLayer(trackLayer);
let index = 0;
function replayTrack() {
if (index >= trackFeatures.length) {
index = 0;
}
const feature = trackFeatures[index];
const coordinate = feature.getGeometry().getCoordinates();
map.getView().animate({
center: coordinate,
duration: 1000,
});
index++;
setTimeout(replayTrack, 1000);
}
replayTrack();
const extent = trackSource.getExtent();
map.getView().fit(extent, {
padding: [50, 50, 50, 50],
duration: 1000,
});
},
};
</script>
```
### 注意事项
- 确保替换 `your-tianditu-api-key` 为实际的天地图 API Key。
- 轨迹点数据可以根据实际需求动态获取或从服务器加载。