[ArcGIS API for JavaScript 4.8] Sample Code-Get Started-layers简介
【官方文档:https://developers.arcgis.com/javascript/latest/sample-code/intro-layers/index.html】
一、Intro to layers
地图是由许多图层构成的,图层(layer)是地图的重要组件,通过展示空间数据来表现实际生活现象。图层可以表示矢量要素(vector),也可以表示栅格要素(raster)。JS API中可以使用很多种类的图层(layer),具体类别请查看文档:https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-Layer.html#layer-types。
1.代码骨架
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <!-- 移动端优化 --> 6 <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"> 7 <title>Intro to layers</title> 8 9 <!-- JS API的引入 --> 10 <link rel="stylesheet" href="https://js.arcgis.com/4.8/esri/css/main.css"> 11 <script src="https://js.arcgis.com/4.8/"></script> 12 13 <script> 14 15 </script> 16 17 <!-- 设置样式,正确显示地图 --> 18 <style> 19 html,body,#viewDiv{ 20 padding:0; 21 margin:0; 22 height:100%; 23 width:100%; 24 } 25 </style> 26 </head> 27 28 <body> 29 <div id="viewDiv"></div> 30 </body> 31 </html>
其中包括,JS API的引入、style样式的设置等等。
2.创建地图(Map)和3D视图(SceneView)
1 <script> 2 require([ 3 "esri/Map", 4 "esri/views/SceneView", 5 "dojo/domReady!" 6 ],function(Map,SceneView){ 7 // 创建地图 8 var map=new Map({ 9 basemap:"oceans" 10 }); 11 12 // 创建SceneView 13 var view=new SceneView({ 14 container:"viewDiv", 15 map:map 16 }); 17 }); 18</script>
3.创建切片图层(TileLayer)
每一个图层(layer)都有一个url属性,这个url可以来自ArcGIS Server发布的服务或者是portal中的地图内容。不同的url标识不同的图层,每个图层都只有唯一的url。这里使用Esri World Transportation service提供的地图服务。
1 <script> 2 require([ 3 "esri/Map", 4 "esri/views/SceneView", 5 "esri/layers/TileLayer", // 需要新添加的模块 6 "dojo/domReady!" 7 ],function(Map,SceneView,TileLayer){ // 注意这里也需要添加对应的类 8 // 创建地图 9 var map=new Map({ 10 basemap:"oceans" 11 }); 12 13 // 创建SceneView 14 var view=new SceneView({ 15 container:"viewDiv", 16 map:map 17 }); 18 19 var transportationLayer=new TileLayer({ 20 url:"https://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer", 21 id:"streets", // 设置其他一些属性 22 opacity:0.7 23 }); 24 25 var housingLayer=new TileLayer({ 26 url:"https://tiles.arcgis.com/tiles/nGt4QxSblgDfeJn9/arcgis/rest/services/New_York_Housing_Density/MapServer", 27 id:"ny-housing" 28 }); 29 }); 30</script>
"esri/layer/TileLayer"是新添加的模块,在function()也要添加相应的类。
创建两个TileLayer切片图层,设置相应url和其他相关属性,url由Esri提供。id是对图层的标识,opacity设置图层的透明度。还有一些属性,比如minScale和maxScale控制图层在不同比例尺下的可见性,以增强图层在地图上的表达合理性。visible属性为true显示图层,为false使图层不可见。
4.添加图层到地图
将创建好的图层添加到地图上有很多种方式,具体请查看文档:https://developers.arcgis.com/javascript/latest/api-reference/esri-Map.html#layers。
这里给出两种方式:①在Map构造函数中设置相关属性 ②通过Map实例的方法添加
第一种方法:在Map构造函数中设置layers属性以添加相应图层(这种方法未成功实现)
1 var map=new Map({ 2 basemap:"oceans", 3 layers:[housingLayer] // 设置的属性 4 });
但是运行结果报错,错误信息如下:
(更新:这种方法是可行的,之前报错是因为housingLayer在实例化Map之后才定义,相当于给layers属性添加了一个未定义的图层)
第二种方法:通过Map实例的方法添加
1 map.layers.add(housingLayer); 2 map.layers.add(transportationLayer);
这样就将之前创建的图层添加到了底图上,最终运行效果如下。可以看到交通线和纽约地区的城市面都已添加到底图Oceans上。
5.在页面中控制图层的显示与隐藏
在<body>中添加checkbox控件。注意checkbox的id,后面会用到。
1 <body> 2 <div id="viewDiv"> 3 <span id="layerToggle"> 4 <input type="checkbox" id="streetsLayer" checked>Transportation 5 </span> 6 </div> 7</body>
当点击checkbox时,会触发change事件,以控制图层的visible属性。监听change事件需要导入"dojo/on"模块和"dojo/dom"模块。"dojo/on"用于监听HTML DOM上的事件,"dojo/dom"用于获得DOM元素。
1 <script> 2 require([ 3 "esri/Map", 4 "esri/views/SceneView", 5 "esri/layers/TileLayer", // 需要新添加的模块 6 "dojo/dom", // 用于获取HTML DOM元素 7 "dojo/on", // 用于监听HTML DOM元素上的事件 8 "dojo/domReady!" 9 ],function(Map,SceneView,TileLayer,dom,on){ // 注意这里也需要添加对应的类 10 // 创建地图 11 var map=new Map({ 12 basemap:"oceans", 13 }); 14 15 // 创建SceneView 16 var view=new SceneView({ 17 container:"viewDiv", 18 map:map 19 }); 20 21 var transportationLayer=new TileLayer({ 22 url:"https://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer", 23 id:"streets", // 设置其他一些属性 24 opacity:0.7 25 }); 26 27 var housingLayer=new TileLayer({ 28 url:"https://tiles.arcgis.com/tiles/nGt4QxSblgDfeJn9/arcgis/rest/services/New_York_Housing_Density/MapServer", 29 id:"ny-housing", 30 31 }); 32 33 map.layers.add(housingLayer); 34 map.layers.add(transportationLayer); 35 36 // 获取checkbox元素,通过dom.byId()方法 37 var streetsLayerToggle=dom.byId("streetsLayer"); 38 39 // 监听checkbox的change事件 40 on(streetsLayerToggle,"change",function(){ 41 // 当checkbox为true时,图层的visible也为true 42 transportationLayer.visible=streetsLayerToggle.checked; 43 }); 44 }); 45</script>
通过dojo提供的dom.byId()方法获取checkbox元素。使用dojo提供的on()方法对checkbox改变状态这一事件进行监听,并设置响应行为。on()有3个参数,第一个参数是监听的对象,这里是指向checkbox的那个变量。第二个参数是监听事件,这里是"change"。第三个参数是一个匿名函数,即事件发生时的响应行为。这里是将transportationLayer图层的可见性设置成checkbox的状态属性,以起到显示图层与隐藏图层的功能。
这里要注意,当图层的visible属性为false时,它仍是Map地图的一部分,仍添加在这个地图中,只是看不见而已,但它是存在的。依然可以访问这个图层的属性,或使用这个图层进行一些分析操作。
现在通过勾选checkbox,以进行transportationLayer图层的显示与隐藏。
6.理解图层视图(LayerView)
图层(layer)是发布的地图服务,包含着地理数据和属性数据的信息。当图层在视图View中加载完成时,会创建一个LayerView。可以理解成View之下显示layer的一个东西。当图层加载完成时(即LayerView创建时),会触发视图View的"layerview-create"事件。下面为function(){}中添加的代码。
1 // 图层加载完成时将生成LayerView 2 // 将触发View的"layerview-create"事件 3 view.on("layerview-create",function(event){ 4 if(event.layer.id==="ny-housing"){ 5 // 加载的是housingLayer 6 console.log("LayerView for New York housing density created!",event.layerView); 7 }; 8 if(event.layer.id==="streets"){ 9 // 加载的是transportationLayer 10 console.log("LayerView for streets created!",event.layerView); 11 }; 12 });
当view的"layerview-create"事件触发后,进行layer.id的判断以显示相对应的信息。
7.使用Layer.when()
一个图层(layer)就是一个promise(promise的详细概念请参考文档:https://developers.arcgis.com/javascript/latest/guide/working-with-promises/index.html)
Layer.when()方法的作用是当图层加载完成后,再进行一些行为。这里,当housing layer加载完成后,想要让地图缩放到适合的比例尺及这个图层所在的地区(纽约地区)。在function(){}中添加如下代码。
1 // 当housing layer加载完成后,缩放到这个图层的fullExtent 2 housingLayer.when(function(){ 3 view.goTo(housingLayer.fullExtent); 4 });
view.goTo()是将视角移到别的地方。
这样设置后,页面先显示出整个地球,接着跳到纽约那边图层区域。
8.最终代码
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <!-- 移动端优化 --> 6 <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"> 7 <title>Intro to layers</title> 8 9 <!-- JS API的引入 --> 10 <link rel="stylesheet" href="https://js.arcgis.com/4.8/esri/css/main.css"> 11 <script src="https://js.arcgis.com/4.8/"></script> 12 13 <script> 14 require([ 15 "esri/Map", 16 "esri/views/SceneView", 17 "esri/layers/TileLayer", // 需要新添加的模块 18 "dojo/dom", // 用于获取HTML DOM元素 19 "dojo/on", // 用于监听HTML DOM元素上的事件 20 "dojo/domReady!" 21 ],function(Map,SceneView,TileLayer,dom,on){ // 注意这里也需要添加对应的类 22 // 创建地图 23 var map=new Map({ 24 basemap:"oceans", 25 }); 26 27 // 创建SceneView 28 var view=new SceneView({ 29 container:"viewDiv", 30 map:map 31 }); 32 33 var transportationLayer=new TileLayer({ 34 url:"https://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer", 35 id:"streets", // 设置其他一些属性 36 opacity:0.7 37 }); 38 39 var housingLayer=new TileLayer({ 40 url:"https://tiles.arcgis.com/tiles/nGt4QxSblgDfeJn9/arcgis/rest/services/New_York_Housing_Density/MapServer", 41 id:"ny-housing", 42 43 }); 44 45 map.layers.add(housingLayer); 46 map.layers.add(transportationLayer); 47 48 // 获取checkbox元素,通过dom.byId()方法 49 var streetsLayerToggle=dom.byId("streetsLayer"); 50 51 // 监听checkbox的change事件 52 on(streetsLayerToggle,"change",function(){ 53 // 当checkbox为true时,图层的visible也为true 54 transportationLayer.visible=streetsLayerToggle.checked; 55 }); 56 57 // 图层加载完成后将生成LayerView 58 // 将触发View的"layerview-create"事件 59 view.on("layerview-create",function(event){ 60 if(event.layer.id==="ny-housing"){ 61 // 加载的是housingLayer 62 console.log("LayerView for New York housing density created!",event.layerView); 63 }; 64 if(event.layer.id==="streets"){ 65 // 加载的是transportationLayer 66 console.log("LayerView for streets created!",event.layerView); 67 }; 68 }); 69 70 // 当housing layer加载完成后,缩放到这个图层的fullExtent 71 housingLayer.when(function(){ 72 view.goTo(housingLayer.fullExtent); 73 }); 74 }); 75 </script> 76 77 <!-- 设置样式,正确显示地图 --> 78 <style> 79 html,body,#viewDiv{ 80 padding:0; 81 margin:0; 82 height:100%; 83 width:100%; 84 } 85 </style> 86 </head> 87 88 <body> 89 <div id="viewDiv"> 90 <span id="layerToggle"> 91 <input type="checkbox" id="streetsLayer" checked>Transportation 92 </span> 93 </div> 94 </body> 95 </html>
关于Layer的更多信息,请参考文档:https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-Layer.html