239 lines
9.0 KiB
Markdown
239 lines
9.0 KiB
Markdown
---
|
||
title: View 示例
|
||
date: 2021-09-08
|
||
author: ac
|
||
tags:
|
||
- OpenLayers
|
||
categories:
|
||
- GIS
|
||
---
|
||
|
||
## [View Animation](https://openlayers.org/en/latest/examples/animation.html) 示例
|
||
|
||
> 开始学`ol`会觉得很奇怪,因为从`ArcGIS API for JS 3.x`刚转过来,它里面并没有将控制分辨率、缩放级别、地图范围、投影等分离出来,这些相关的API全在map对象里面,而`ol`将它们封装到了`View`中。
|
||
|
||
### 1 View对象
|
||
|
||
`View`对象是代表地图的简单`2D`视图,可以用于更改地图中心、分辨率、和旋转的对象;其中的projection属性,确定地图的坐标系(默认是墨卡托投影`EPSG:3857`)。
|
||
|
||
View有三种状态:
|
||
|
||
- center:视图的初始中心。
|
||
- resolution:视图的初始分辨率。单位是projection每像素的单位(例如米/像素),所有关于地图缩放有关的计算都是使用`resolution`。
|
||
- rotation:视图的初始旋转(弧度)(顺时针正旋转,0表示北)。
|
||
|
||
跟地图缩放有关的还有`zoom`属性,但实际上`zoom`没有封装在`view`对象中,不过`view`中还是提供了`setZoom()`和`getZoom()`方法访问`zoom`属性。
|
||
|
||
### 2 状态的限制
|
||
|
||
通过`setCenter`、`setResolution`和`setRotation`方法可以改变view的状态。但地图不可能无限的放大或缩小,所以使用`resolutions`设置地图的所有层级的分辨率或使用`maxResolution`、`MaxZoom`和`zoomFactor`限制缩放的大小。如果设置了`resolutions`属性,其他三个属性将失效。
|
||
|
||
|
||
|
||
### 3 Animation动画
|
||
|
||
当改变view状态的时候,可以使用`animate(option)`方法从原来的状态平滑的过渡到另一个状态。
|
||
|
||
`option`配置对象,以`JSON`对象的方式配置参数,同时也可以有多个配置对象形成链式连续的动画效果。
|
||
|
||
| type | Description |
|
||
| :--------: | ------------------------------------------------------------ |
|
||
| center | 动画结束后view的中心 |
|
||
| zoom | 动画结束后view的缩放级别,优先于`resolution` |
|
||
| resolution | 动画结束后view的地图分辨率,如果设置了`zoom`则该配置项会被忽略 |
|
||
| rotation | 动画结束后view的旋转角度,顺时针正旋转,0表示北 |
|
||
| anchor | 锚点,是一个Coordinate类型的参数,用于固定某点进行动画 |
|
||
| duration | 动画的过渡时间,单位为毫米 |
|
||
| easing | 动画使用的缓冲函数。该函数将为每一帧调用,并带有表示动画持续时间的一小部分的数字。应该返回一个0到1之间的数字,表示向目标状态的进展。 |
|
||
|
||
```html
|
||
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<style>
|
||
.map {
|
||
height: 400px;
|
||
width: 100%;
|
||
}
|
||
</style>
|
||
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/build/ol.js"></script>
|
||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/css/ol.css">
|
||
<title>View</title>
|
||
</head>
|
||
<body>
|
||
<h2>My Map</h2>
|
||
<div id="map" class="map"></div>
|
||
<script type="text/javascript">
|
||
|
||
window.onload =function(){
|
||
var shenzhen = [113.958334,22.535640];
|
||
/*
|
||
* 地图表现:必备三要素,
|
||
* 图层(Layer)
|
||
* 视图(View)
|
||
* 目标容器(target)
|
||
* */
|
||
var map = new ol.Map({
|
||
view:new ol.View({
|
||
center:ol.proj.fromLonLat(shenzhen),
|
||
zoom:8,
|
||
minzoom:6,
|
||
maxzoom:12,
|
||
rotation:Math.PI/6
|
||
}),
|
||
layers:[
|
||
new ol.layer.Tile({
|
||
source:new ol.source.OSM()
|
||
})
|
||
],
|
||
target:"map"
|
||
});
|
||
map.on("click",function (e) {
|
||
var point = e.coordinate;
|
||
console.log("x:"+point[0]+",y:"+point[1]);
|
||
});
|
||
/*
|
||
*View对象:
|
||
*View对象是代表地图的简单2D视图,可以用于更改地图中心、分辨率、和旋转的对象;
|
||
* projection属性,确定中心的坐标系(默认是墨卡托投影EPSG:3857)
|
||
*
|
||
* View三种状态:
|
||
* center:视图的初始中心。如果未设置用户投影,则使用projection选项指定中心的坐标系,如果未设置,则不会获取图层源,但是稍后可以使用设置中心#setCenter。
|
||
* resolution:视图的初始分辨率。单位是projection每像素的单位(例如米/像素)
|
||
* rotation:视图的初始旋转(弧度)(顺时针正旋转,0表示北)。
|
||
*
|
||
* 常用属性还有:zoom,resolutions。如果设置了resolutions,则maxResolution,minResolution, minZoom,maxZoom,和zoomFactor选项都将被忽略。
|
||
*/
|
||
//地图视图的初始化参数
|
||
var view = map.getView();
|
||
var zoom = view.getZoom();
|
||
var center = view.getCenter();
|
||
var rotation = view.getRotation();
|
||
|
||
document.getElementById("zoom-out").onclick = function(e){
|
||
var view = map.getView();
|
||
var zoom = view.getZoom();
|
||
view.setZoom(zoom - 1);
|
||
};
|
||
|
||
document.getElementById("zoom-in").onclick = function(e){
|
||
var view = map.getView();
|
||
var zoom = view.getZoom();
|
||
view.setZoom(zoom + 1);
|
||
};
|
||
|
||
document.getElementById("panto").onclick = function(e){
|
||
var view = map.getView();
|
||
//参数为ol.Coordinate
|
||
var mak = ol.proj.fromLonLat(shenzhen);
|
||
view.setCenter(mak);
|
||
};
|
||
|
||
document.getElementById("reset").onclick = function(e){
|
||
view.setCenter(center);
|
||
view.setZoom(zoom);
|
||
view.setRotation(rotation);
|
||
};
|
||
|
||
// var shenzhen = [1280091112800911.302100137,2611260.0825854577];
|
||
/*
|
||
animate(var_args)
|
||
例子: view.animate({zoom: view.getZoom() + 1});
|
||
view.animate({zoom: 10}, {center: [0, 0]});将多个动画放在一起,先缩放后平移
|
||
|
||
参数:center、zoom、resolution、rotation、duration、easing、anchor
|
||
默认情况下,动画持续一秒钟,并 in-and-out easing缓进缓出,
|
||
duration:设置动画持续时间(单位:毫秒);
|
||
easing:设置动画进出方式;
|
||
anchor锚点:用于rotation或resolution固定旋转的原点;
|
||
**/
|
||
document.getElementById("rotate-left").onclick = function (e) {
|
||
view.animate({
|
||
rotation:view.getRotation()+Math.PI/2
|
||
});
|
||
};
|
||
|
||
document.getElementById("rotate-right").onclick = function (e) {
|
||
view.animate({
|
||
rotation:view.getRotation()-Math.PI/2
|
||
});
|
||
};
|
||
|
||
document.getElementById("fly-to-shenzhen").onclick = function () {
|
||
var rotation = view.getRotation();
|
||
flyTo(shenzhen,function () {
|
||
console.log("执行完回调");
|
||
});
|
||
};
|
||
function flyTo(location, done) {
|
||
var duration = 2000;
|
||
var zoom = view.getZoom();
|
||
var parts = 2;
|
||
var called = false;
|
||
function callback(complete) {
|
||
--parts;
|
||
if (called) {
|
||
return;
|
||
}
|
||
if (parts === 0 || !complete) {
|
||
called = true;
|
||
done(complete);
|
||
}
|
||
}
|
||
view.animate({
|
||
center: ol.proj.fromLonLat(shenzhen),
|
||
duration: duration
|
||
}, callback);
|
||
view.animate({
|
||
zoom: zoom - 1,
|
||
duration: duration / 2
|
||
}, {
|
||
zoom: zoom,
|
||
duration: duration / 2
|
||
}, callback);
|
||
}
|
||
|
||
/**
|
||
* 注意:当多个option配置对象时,每个状态(zoom,resolution,rotation)都是相对原始状态的
|
||
*/
|
||
document.getElementById("rotate-around-shenzhen").onclick = function(){
|
||
var rotation = view.getRotation();
|
||
view.animate({
|
||
rotation: rotation + Math.PI,//是原始状态旋转180
|
||
anchor: ol.proj.fromLonLat(shenzhen),
|
||
easing: ol.easing.easeIn
|
||
},{
|
||
rotation: rotation + 2*Math.PI,//是原始状态旋转360
|
||
anchor: ol.proj.fromLonLat(shenzhen),
|
||
easing: ol.easing.easeOut
|
||
})
|
||
}
|
||
}
|
||
</script>
|
||
<hr>
|
||
<div>
|
||
<p>View动画animation</p>
|
||
<p>让View平滑地改变状态(中心点、缩放级别、旋转)</p>
|
||
<button id="zoom-out">放大</button>
|
||
<button id="zoom-in">缩小</button>
|
||
<button id="panto">定位</button>
|
||
<button id="reset">复位</button>
|
||
<button id="rotate-left" title="Rotate clockwise">↻</button>
|
||
<button id="rotate-right" title="Rotate counterclockwise">↺</button>
|
||
<button id="rotate-around-shenzhen">Rotate around shenzhen</button>
|
||
<button id="fly-to-shenzhen">Fly to ShenZhen</button>
|
||
</div>
|
||
</body>
|
||
</html>
|
||
```
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|