好了,先来看看这个案例是什么样子的,作用就是小地图随着主地图显示范围。官网的案例名为:overview-map
一:老样子,骨架先给出,有助于理解整个代码。
var mainMap = new Map();
var mainView = new SceneView();
var mapView = new MapView();
mapView.ui.components = [];
mapView.when(function () {});
function setup();
由于本文是给一副3D图配置鹰眼图。所以,需要一副主地图加载在SceneView,一副幅地图加载在MapView。
前三行骨架就是这个作用了。
第四行是把esri加载所附带的放大按钮等小部件给删除。
mapView.when就是等待用户移动主地图,鹰眼图的变化。setup是when调用的方法。
接下来看具体代码。
二、代码细节
1、将带有三维地形的Map放入SceneView中加载,
var mainMap = new Map({
basemap: "hybrid",
ground: "world-elevation"
});
// Create another Map, to be used in the overview "view"
var overviewMap = new Map({
basemap: "topo"
});
加载两个map,一个有 ground,带有地形起伏,等一下用SceneView加载为三维地图。
2、加载到View中。
var mainView = new SceneView({
container: "viewDiv",
map: mainMap,
camera: {
position: {
spatialReference: {
latestWkid: 3857,
wkid: 102100
},
x: 925151,
y: 5956309,
z: 3871
},
heading: 203,
tilt: 72
}
});
// Create the MapView for overview map
var mapView = new MapView({
container: "overviewDiv",
map: overviewMap,
constraints: {
rotationEnabled: false
}
});
这个编辑器缩进有点迷。
这边要说一下wkid,他和lastwkid其实是一个东西,只是这个坐标系改名了而已。为了在系统兼容性。camera就是加载三维图的视角问题。相当于你看一个世界,总有视角吧,看一个杨桃,有一个方向是能看到星星的。知道作用就行,具体属性查API。
3、删除默认小工具,并写when事件。
mapView.ui.components = [];
mapView.when(function () {
mainView.when(function () {
setup();
});
});
when就是加载完之后等待用户操作地图发生的事件,而then是没人操作,他在完成了页面加载后,所要做的事,没学过es6的我,一开始真的是蒙的一批。本例中,因为发生变化的是mapView,所以给他添加方法,他又是因为主地图变化的,所以又写一层主地图的when事件,最后因为主地图改变,执行setup方法。有点像C#里面的委托,执行过程就是mapView看管着小地图,然后平时就是看着SceneView,看他到底在干嘛,总是跟着他学。这天,用户把SceneView的地图动了一下,这一切mapView是看在眼里的,你都动了,我没动岂不是很没面子?那我也动一下吧。就这样实现同步移动。下一模块说怎么动。
4、鹰眼具体实现。
function setup() {
const extent3Dgraphic = new Graphic({
geometry: null,
symbol: {
type: "simple-fill",
color: [0, 0, 0, 0.5],
outline: null
}
});
mapView.graphics.add(extent3Dgraphic);
watchUtils.init(mainView, "extent", function (extent) {
// Sync the overview map location
// whenever the 3d view is stationary
if (mainView.stationary) {
mapView
.goTo({
center: mainView.center,
scale:
mainView.scale *
2 *
Math.max(
mainView.width / mapView.width,
mainView.height / mapView.height
)
})
.catch(function (error) {
// ignore goto-interrupted errors
if (error.name != "view:goto-interrupted") {
console.error(error);
}
});
}
extent3Dgraphic.geometry = extent;
});
说这个之前得先说下地图上的显示内容,可以有各种各样的图,还有一个就是绘制的图,比如点线面,后面绘制的,统统在Graphic这个类里面。想要画一个东西并显示在地图上,就得实例化一个Graphic,然后用mapView的 graphics属性去接收。
所以一开始实例化graphic的 作用就在于此。一开始为什么要设置为空呢,就是因为每移动一次图,就得把原来的graphic清除,那很麻烦的,那我干脆声明一个常量,后面通过改变属性geometry就好。每次运行都给他从新设置为空。提高了效率。
watchUtils.init查询API可知,用于监视访问器属性的各种实用工具。监视属性的更改并使用属性的初始值调用回调。
这里监视了mainView,用户拖动地图,extent会变化,不懂extent的自行查询API,其实就是范围。
执行的回调函数为副地图把中心跳转过去,这样就实现了两幅图连接在一起。然后改变scale缩放比例,这个数学公式我也搞不懂,反正通过这个缩放比例,graphic可以刚好生成鹰眼小框框。
好,就是这样了,写起来挺简单的,当初弄了挺久。
三、总结
1、两幅图该如何连接?同步显示?
通过watchUtils.init,监视地图的变化,只要查看地图的属性,就可以为不同的属性添加不同的监听方法。要同步显示,就是监听extent属性。
2、鹰眼实现思路
主地图动,小地图改变中心,改变scale,然后获取主地图的extent,赋给鹰眼graphic的geomet属性。小地图添加graphic。其中,scale的公式为scale:mainView.scale *2*Math.max(mainView.width / mapView.width,mainView.height / mapView.height)
3、给地图添加起伏效果
设置Map中属性ground: "world-elevation"
下期再见。