全球高精度土地利用数据服务 全国作物类型空间分布数据服务 二级分类土地利用数据30m 高精度植被类型分布数据 全国城市功能区划分布数据 全国DEM高程数据服务 全国耕地数据空间分布服务 全国林地分类数据空间分布服务 全国草地类型分类数据空间分布服务 全国水体数据空间分布服务 全国建设用地数据空间分布服务 全国未利用地数据空间分布服务 地形、地貌、土壤理化性质数据服务 全国坡度坡向数据服务 一级分类土地利用数据30m
全国降水量空间分布数据集 全国气温空间分布数据集 太阳辐射量空间分布数据集 全国气象站点观测数据集 全国平均风速空间分布数据集 全国平均水汽压空间分布数据集 全国蒸散量空间分布数据集 全国日照时数空间分布数据集 全国相对湿度空间分布数据集 全国地表温度空间分布数据集 全国气候区划空间分布数据集 全国气象站点空间分布数据集 全国土壤湿度空间分布数据集 全国水文站点地表径流量空间分布数据集
土壤类型空间分布数据服务 土壤质地空间分布数据服务 土壤有机质空间分布数据服务 土壤酸碱度空间分布数据服务 土壤氮磷钾空间分布数据服务 土壤深度空间分布数据服务 土壤侵蚀强度空间分布数据服务 土壤含水量空间分布数据服务 土壤重金属含量空间分布数据服务 中国土壤阳离子交换量空间分布数据 中国土壤容重含量空间分布数据
全国夜间灯光指数数据服务 全国GDP公里格网数据服务 全国人口密度数据服务 全国poi感兴趣点空间分布数据 全国医院空间分布数据服务 全国学校空间分布数据服务 全国居民点空间分布数据 全国旅游景区空间分布数据 全国机场空间分布数据 全国地铁线路站点空间分布数据 人口调查空间分布数据服务 社会经济统计年鉴数据 中国各省市统计年鉴 中国县级统计年鉴数据 农田分类面积统计数据服务 农作物长势遥感监测数据服务 医疗资源统计数据服务 教育资源统计数据服务 行政区划空间分布数据服务
Landsat陆地资源卫星影像 高分二号遥感影像数据 高分一号遥感影像数据 Sentinel2哨兵2卫星影像 SPOT系列卫星遥感影像数据 WorldView卫星遥感影像数据 资源三号卫星遥感影像数据 GeoEye卫星遥感影像数据 NOAA/AVHRR卫星遥感影像 MODIS卫星遥感影像 环境小卫星 Rapideye快鸟卫星影像
高精度归一化植被指数NDVI空间分布数据 高精度净初级生产力NPP空间分布数据 LAI叶面积指数空间分布数据 全国地表温度LST空间分布数据 全国生态系统服务空间数据集 全国湿地沼泽分类空间分布数据集 全国陆地生态系统类型空间分布数据集 全国农田生产潜力数据集 全国GPP初级生产力数据 全国农田熟制空间分布数据集 中国植被区划数据 中国草地资源数据 全国月度NDVI归一化植被指数空间分布数据 月度净初级生产力NPP空间分布数据 全国年度NDVI归一化植被指数空间分布数据 年度净初级生产力NPP空间分布数据 增强型植被指数EVI空间分布数据 RVI比值植被指数空间分布数据
ArcGIS API For JavaScript是事件驱动的API。事件发生在您与JavaScript应用程序交互时,加载页面、单击鼠标、执行任务和许多其他操作都会触发事件。您可以通过监听事件并编写响应事件的代码使应用程序具有交互性,这就是所谓的“处理”事件。
1、为什么ArcGIS API For JavaScript是事件驱动的API?
事件的使用主要有两个主要原因:
①JavaScript API 是异步的,对象上的每个操作都不是立即返回结果。在对象使用之前,可能需要到服务器获取附加信息。
②事件模型允许对每个事件执行多个事件处理程序,您可以根据对象触发的单个事件执行多个操作
2、添加和删除事件监听器
为了处理一个事件,您需要添加监听事件的代码。为事件注册监听器会提醒您的应用程序在发生特定事件时需要执行一些操作。特别是,它将调用事件处理函数来响应事件。
在ArCGIS API For JavaScript中,监听事件的推荐方法是使用on关键字。也可以使用dojo/aspect或者旧的dojo/_base/connect模块来监听或响应事件。从3.6版本开始,ArcGIS API中的所有模块都支持on()形式的事件监听器。
下面的代码演示了如何使用这两种方法:
①使用on方法:
var mapExtentChange = map.on("extent-change", changeHandler);
function changeHandler(evt){
var extent = evt.extent,
zoomed = evt.levelChange;
// ... Do something ...
// in some cases, you may want to disconnect the event listener
mapExtentChange.remove();
}
on方法的参数:
②使用dojo/_base/connect(dojo.connect)模块:
require(["dojo/_base/connect", "esri/map"],function(connect, Map) {
...
var mapExtentChange_connect = connect.connect(map, "onExtentChange", changeHandler_connect);
function changeHandler_connect(extent, delta, levelChange, lod){
// ... Do something ...
// in some cases, you may want to disconnect the event listener
connect.disconnect(mapExtentChange_connect);
}
}
connect方法的参数:
除了不同的方法签名外,事件处理函数在一个重要的方面上也不同。通过on方法连接的事件监听器接收单个事件对象作为参数,事件信息作为事件对象上的属性进行传递。这与connect方法形成对比,connect方法的监听器被传递为位置参数。另一个重要的区别是事件名称,on方法的事件名称是小写的且没有“on”前缀。
作为最佳的实践,为了避免内存泄漏,应该在关闭应用程序时删除事件监听器。这是通过添加另一个监听器来完成的。下面是针对map的onUnload事件的例子:
①使用on方法
var myUnload = map.on("unload", unloadHandler);
②使用connect方法
var myUnload_connect = connect.connect(map, "onUnload", unloadHandler_connect);
或者您可以注册在窗口unload时要调用的unload处理程序:
dojo.addOnUnload(myUnloadHandler);
在"unload"事件处理函数中,您可以在"onUnload"取消任何的事件监听器
①使用on方法
function unloadHandler(evt){
changeHandler.remove();
myUnload.remove();
}
②使用connect方法
function unloadHandler_connect(map){
connect.disconnect(changeHandler_connect);
connect.disconnect(myUnload_connect);
}
3、on方法和connect方法的比较
使用on方法比使用connect方法更可取:
①首先,Dojo文档声明connect方法将Dojo2.0中删除,实际上,connect方法实际是dojo.on的遗留产物
②其次,特别是在AMD风格中,它使您的代码更少,并且更类似于其他JavaScript框架中的事件添加语法
③最后,对于Esri组件,我们向所有“synthetic”事件(不是鼠标或者键盘事件)添加了一个target属性,该属性指向触发事件的组件。由于事件处理程序异步触发,并且不能保证事件处理程序的全部内容被触发,但是,evt.Target的值是可靠的。
require([
"dojo/_base/lang","esri/map", "esri/layers/WebTiledLayer", ...
], function(lang, Map, WebTiledLayer, ...) {
var map = new Map("mapDiv"),
layer = new WebTiledLayer(...);
map.on("load", lang.hitch(layer, mapLoaded));
...
function mapLoaded(evt) {
var map = evt.target;
console.log("Initial Map Extent: ", map.extent.toJson());
// this function is executing with a scope "hitch"-ed to layer
console.log("Full Layer Extent: ", this.fullExtent.toJson());
}
});
4、普通事件
本节提供了处理ArcGIS API For JavaScript中常见事件的一些提示
Map 的"load"事件
当您将map添加到页面时,您不能立即使用它,直到第一个layer被添加到map您才能使用map。向map中添加一个layer将初始化graphics并触发onLoad事件,此时,您可以与map进行交互。此规则的一个例外是setExtent()方法,您可以在map的构造函数中设置map的初始化extent,或者在添加第一个layer之前调用setExtent()方法改变map的extent。
①使用on方法:
require(["esri/map", ...], function(Map, ...) {
var map = new Map("mapDiv"),
mapOnLoad = map.on("load", configNavigation);
map.addLayer(...);
function configNavigation(evt) {
evt.map.disableMapNavigation();
}
});
②使用connect方法:
require(["esri/map", "dojo/_base/connect", ...], function(Map, connect, ...) {
var map = new Map("mapDiv"),
mapOnLoad = connect.connect(map, "onLoad", configNavigation);
map.addLayer(...);
function configNavigation(map) {
map.disableMapNavigation();
}
});
ArcGISDynamicMapServiceLayer的"load"事件和ArcGISTiledMapServiceLayer 的"load"事件
esri.layers.ArcGISDynamicMapServiceLayer和esri.layers.ArcGISTiledMapServiceLayer与ArcGIS Server 的REST服务端点一起工作。当第一次创建该layer时,它需要向ArcGIS Server发出请求以获取服务信息,您应该等到该layer的onLoad事件被触发后再与该layer交互。下面的代码使用事件处理程序在onLoad事件触发之后访问初始的extent属性。
①使用on方法:
require(["esri/layers/ArcGISDynamicMapServiceLayer", ... ], function(ArcGISDynamicMapServiceLayer, ... ){
var layer = new ArcGISDynamicMapServiceLayer(...);
layer.on("load", printInitialExtent);
function printInitialExtent(evt) {
alert(evt.layer.initialExtent);
}
});
②使用connect方法:
require([
"dojo/_base/connect","esri/layers/ArcGISDynamicMapServiceLayer", ...
], function(connect, ArcGISDynamicMapServiceLayer, ... ) {
var layer = new ArcGISDynamicMapServiceLayer(...);
connect.connect(layer, "onLoad", printInitialExtent);
function printInitialExtent(layer) {
console.log(layer.initialExtent);
}
});
在浏览器中,由于资源缓存,一旦layer被构造,onLoad事件就会被触发。因此,在为"Load"事件注册事件监听器之前,您应该检查该层的loaded属性是否为true:
①使用on方法:
require(["esri/layers/ArcGISDynamicMapServiceLayer", ...
], function(ArcGISDynamicMapServiceLayer, ... ) {
var layer = new ArcGISDynamicMapServiceLayer(...);
if(layer.loaded){
printInitialExtent({"layer":layer});
} else {
layer.on("load", printInitialExtent);
}
function printInitialExtent(evt) {
console.log(evt.layer.initialExtent);
}
});
然而,on方法有一个辅助函数emit,我们可以使用emit来强制事件触发,而不是直接调用事件处理程序:
①使用on方法:
require(["esri/layers/ArcGISDynamicMapServiceLayer", ... ], function(ArcGISDynamicMapServiceLayer, ... ) {
var layer = new ArcGISDynamicMapServiceLayer(...);
layer.on("load", printInitialExtent);
if(layer.loaded){
layer.emit("load",{
"layer":layer
});
}
function printInitialExtent(evt) {
console.log(evt.layer.initialExtent);
}
});
在map和graphics中的Mouse事件
ArcGIS JavaScript API 的map和graphics提供了大量的mouse事件,用户可以使用这些事件与这些对象交互。
注册和监听map的onClick事件:
①使用on方法:
require(["esri/map", ...], function(Map, ...) {
var map = new Map("mapDiv"),
map.on("click", myClickHandler);
map.addLayer(...);
function myClickHandler(evt) {
...
}
});
②使用connect方法:
require(["dojo/_base/connect", "esri/map", ...], function(connect, Map, ...) {
var map = new Map("mapDiv"),
connect.connect(map, "onClick", myClickHandler);
map.addLayer(...);
function myClickHandler(evt) {
...
}
});
注意,on形式和connect形式的事件处理程序在上面的实例中都有相同的签名。因为,鼠标和键事件都用单个事件对象触发,这些事件的处理程序都是相同的,无论使用的是哪种事件绑定方法。
当用户单击map时,会生成一个鼠标事件并调用所有已注册的单击处理程序,鼠标事件对象作为参数传递给每个事件处理程序。除了浏览器提供的所有属性外,事件的属性还包括mapPoint和screenPoint,mapPoint表示在map的坐标系统中鼠标单击的坐标,screenPoint表示屏幕坐标系统中鼠标单击的坐标。
function myClickHandler(event) {
alert("User clicked at " +
event.screenPoint.x + ", " + event.screenPoint.y +
" on the screen. The map coordinate at this point is " +
event.mapPoint.x + ", " + event.mapPoint.y
);
}
除了mapPoint和screenPoint属性之外,返回的事件对象还包括一个graphic属性,它是接收事件的esri.Graphic对象。下面的代码显示了如何处理map的onClick事件,以报告哪个graphic被用户点击。注意,onClick事件只有在map的onLoad事件触发后才有效,在这种情况下,监听器依赖于另一个监听器。
①使用on方法:
require(["esri/map", ...], function(Map, ...) {
var map = new Map("mapDiv"),
mapOnLoad = map.on("load", function(){
map.graphics.on("click", myGraphicsClickHandler);
});
map.addLayer(...);
function myGraphicsClickHandler(evt) {
alert("User clicked on " + evt.graphic);
}
});
②使用connect方法:
require(["esri/map", "dojo/_base/connect", ...], function(Map, connect, ...) {
var map = new Map("mapDiv"),
mapOnLoad = connect.connect(map, "onLoad", function() {
connect.connect(map.graphics, "onClick", myGraphicsClickHandler);
});
map.addLayer(...);
function myGraphicsClickHandler(evt) {
alert("User clicked on " + evt.graphic);
}
});
由于Map.graphics对象只有在Map.onLoad事件被触发后才可用,所以您应该等待事件监听器,直到Map的“Load”事件被触发。
Map的“鼠标滚轮”事件
鼠标滚轮事件已经标准化,可以在所有浏览器中使用,一个属性值被添加到MouseScroll/Wheel 事件(Firefox)或者MouseWheel 事件(Internet Explorer/Safari/Chrome/Opera),其中属性值为正数表示鼠标滚轮向上滚动,属性值为负数表示鼠标滚轮向下滚动:
①使用on方法:
map.on("mouse-wheel", myMouseWheelHandler);
②使用connect方法:
connect.connect(map, "onMouseWheel", myMouseWheelHandler);
function myMouseWheelHandler(event) {
alert("Mouse wheel value = " + event.value);
}
6、事件传播(冒泡)
IE事件模型有时会导致同一事件发生在页面中的多个元素上,如果元素重叠,就会发生这种情况。您可以通过停止该事件来阻止事件冒泡。
假设您有一个应用程序,用户可以在其中单击map执行查询,用户还可以单击任意graphic,在单击的位置重新居中地图,假设该graphic具有point geometry:
①使用on方法:
require(["dojo/_base/event",
"esri/map", "esri/tasks/Query", "esri/tasks/QueryTask" ...],
function(event, Map, Query, QueryTask, ...) {
var map = new Map("mapDiv"),
mapOnClick = map.on("click", executeQuery),
mapOnLoad = map.on("load", function(){
map.graphics.on("click", recenterMap);
}),
queryTask = new QueryTask(...);
map.addLayer(...);
function executeQuery(event) {
var query = new Query({
geometry: event.mapPoint
});
queryTask.execute(query, ...);
}
function recenterMap(event) {
map.centerAt(event.mapPoint);
}
});
②使用connect方法:
require(["dojo/_base/event",
"esri/map", "esri/tasks/Query", "esri/tasks/QueryTask" ...],
function(event, Map, Query, QueryTask, ...) {
var map = new Map("mapDiv"),
mapOnClick = connect.connect(map, "onClick", executeQuery),
mapOnLoad = connect.connect(map, "onLoad", function(){
connect.connect(map.graphics, "onClick", recenterMap);
}),
queryTask = new QueryTask(...);
map.addLayer(...);
function executeQuery(event) {
var query = new Query({
geometry: event.mapPoint
});
queryTask.execute(query, ...);
}
function recenterMap(event) {
map.centerAt(event.mapPoint);
}
});
在IE中,当用户单击map来重新居中map时,上面的代码可能会执行不必要的查询。这是因为click事件不仅在graphics容器上触发,而且在也会map的div上触发。为了确保事件不会传播到map div,您可以通过在recenterMap函数中调用事件对象的stop()方法来停止事件:
function recenterMap(evt) {
// event is an alias for dojo/_base/event
event.stop(event);
map.centerAt(evt.mapPoint);
}