meface/docs/article/gis/openlayers/13viewexample.md

239 lines
9.0 KiB
Markdown
Raw Normal View History

2023-11-17 10:54:23 +08:00
---
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则maxResolutionminResolution minZoommaxZoom和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配置对象时每个状态zoomresolutionrotation都是相对原始状态的
*/
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>
```