《JavaScript构建Web和ArcGIS Server应用实战》——2.5 使用地图服务图层

  1. 云栖社区>
  2. 博客>
  3. 正文

《JavaScript构建Web和ArcGIS Server应用实战》——2.5 使用地图服务图层

异步社区 2017-05-02 17:11:00 浏览2164
展开阅读全文

本节书摘来自异步社区《JavaScript构建Web和ArcGIS Server应用实战》一书中的第2章,第2.5节,作者: 【美】Eric Pimpler(派普勒) 更多章节内容可以访问云栖社区“异步社区”公众号查看。

2.5 使用地图服务图层

一幅没有数据图层的地图就像一个画家的空白画板一样。添加到地图中的数据图层让其有意义并为分析奠定了基础。提供数据图层添加到地图中主要有两种类型的地图服务:动态地图服务图层和切片地图服务图层。

动态地图服务图层在运行时创建地图图片并引用地图服务,然后返回图片到应用程序中。这种类型的地图服务或许由一个或多个图层信息构成。图2-4所示为Demograhpics地图服务,它由九个不同的图层构成,分别从不同地理层次代表Demographic信息。


<a href=https://yqfile.alicdn.com/9710ea2e558d6fbde9ca2f714864913b27a7483a.png" >

客户端应用程序显示将花费更多时间,因为它们必须是动态生成的,所以动态地图服务层服务比切片地图服务图层拥有更多功能。在动态地图服务图层中,你可以通过控制图层定义显示的特征,设置地图服务中各图层的可见性并定义图层的瞬时信息。例如,在前面的图中描述的Demographics地图服务图层,你可以选择在你的应用程序中只显示Census Block Group图层。这是一种通过动态地图服务图层提供的功能,而在切片地图服务图层中则没有这样的功能。

切片地图服务图层引用的是一个预先定义好的地图切片缓存而不是动态加载的图片。用最简单的方法来理解切片地图服务,就是将它认为是覆盖在地图表面的网格。网格中的每一个单元格同样大小,用来将地图分割成单独的图片文件,从而成为切片。单个的切片是服务器上存储的图像文件,当需要的时候根据地图范围和比例尺来检索。在不同的地图比例尺下,这个过程会重复执行。当地图在应用程序中显示时,虽然地图由很多单独的切片构成,但是它们看起来是无缝拼接的,如图2-5所示。


<a href=https://yqfile.alicdn.com/1262637c20a8c340fa472b6bc3154fb86c917a65.png" >

这些切片或者缓存地图图层通常用作底图,包括影像图、街道图、地形图或者不常发生变化的数据图层。切片地图服务显示速度更快,因为每次运行时向地图发送一个请求而并无创建图片的开销。

操作图层常覆盖在切片地图上面,这些图层通常为动态图层。虽然它们在执行时慢一点,但是动态地图服务图层有着在运行时仍可以定义外观的优势。

2.5.1 使用图层类
使用ArcGIS APIforJavaScript中的图层类,可以引用宿主在ArcGIS Server和其他地图服务器中的地图服务。所有的图层类继承自Layer这个基类。由于Layer类没有构造函数,所以你不可以专门针对这个类来创建一个对象。你可以简单地通过继承自Layer的子类来定义属性、方法和事件。

如图2-6所示,DynamicMapServiceLayer、TiledMapServiceLayer和GraphicsLayer全部继承自Layer类。DynamicMapServiceLayer和TiledMapServiceLayer也可以作为基类。DynamicMapServiceLayer是动态地图服务的基类,TiledMapServiceLayer是切片地图服务的基类。第3章“添加图形到地图”完全使用图形和GraphicsLayer,所以我们将在本书后面部分讨论这种类型的图层。Layer、DynamicMapServiceLayer和TiledMapServiceLayer都是基类,所以在应用程序中不可以从这些类中指定创建一个对象。


2f1539eaf16a1152b84ca0259c4be568b3a9dab6

2.5.2 切片地图服务图层
如前面部分提到的那样,切片地图服务图层引用预先定好的图片缓存切片拼接在一起显示一幅无缝的地图,它通常用作底图。

如图2-7所示,ArcGISTiledMapServiceLayer类使用在当引用ArcGIS Server暴露的切片(缓存)地图服务时。这种类型的对象使用已经缓存过的切片地图集合,所以性能得以改善。ArcGISTiledMapServiceLayer构造函数接收URL指针指向地图服务,以及一些允许为地图服务指定ID和控制其透明度与可见性的选项。


<a href=https://yqfile.alicdn.com/3e25aba43ab95de18dfaaac0954e81cd5f9c560e.png" >

如下列示例代码,注意ArcGISTiledMapServiceLayer构造函数接收一个引用地图服务的参数。当一个图层的实例创建后,调用接收一个包含引用切片地图服务图层的变量到Map.addLayer()方法中并添加到地图上。

var basemap = new ArcGISTiledMapServiceLayer("http://server.arcgisonline. com/ArcGIS/rest/services/World_Topo_Map/MapServer");
map.addLayer(basemap);

ArcGISTiledMapServiceLayer主要用来快速显示缓存的地图数据。你还可以控制显示数据的层级。比如,你想展示广义的ArcGISTiledMapService的数据,当用户放大到0~6级别时显示州际公路和高速公路,一旦用户进一步放大就切换到更详细的ArcGISTiledMapService。你还可以控制添加到地图上的每个图层的透明度。

2.5.3 动态地图服务图层
顾名思义,如图2-8所示,ArcGISDynamicMapService类用来动态创建ArcGIS Server地图服务。和ArcGISTiledMapServiceLayer一样,ArcGISDynamicMapServiceLayer的构造函数接收一个指向地图服务的URL和一些参数选项用来为服务分配一个ID、设置地图图片的透明度和图层初始可见性选项为true或者false。ArcGISDynamicMapServiceLayer的类名有时有误导性。虽然看上去是引用一个单独的数据图层,但实际上不是。它指的是一个地图服务而不是一个数据图层。地图服务内部的单个图层可以通过setVisibleLayers()方法来打开或者关闭。


bac24b9a1199914b54f3f8cf9a15fe8615c2a646

创建一个ArcGISDynamicMapServiceLayer的实例和ArcGISTiledMapServiceLayer非常类似,下列示例代码说明了这一点。构造函数接收一个指向地图服务的URL参数。第二个参数定义了可选参数,用来控制透明度、可见性和图像参数。

var operationalLayer = new ArcGISDynamicMapServiceLayer("http://sampleserver1. arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Population_World/MapServer",{"opacity":0.5});
map.addLayer(operationalLayer);

如下列代码所示,将上面两行代码添加到ArcGIS API for JavaScript沙盒中。

<script>
  var map;
  require(["esri/map", "esri/layers/ArcGISDynamicMapServiceLayer", 
"dojo/domReady!"], function(Map, ArcGISDynamicMapServiceLayer) {
    map = new Map("mapDiv", {
      basemap: "topo",
      center: [-122.45,37.75], // long, lat
      zoom: 5,
      sliderStyle: "small"
    });
    var operationalLayer = new ArcGISDynamicMapServiceLayer("http://
sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Population_World/MapServer",{"opacity":0.5});
    map.addLayer(operationalLayer);
  });
</script>

运行上面的代码可以看到动态图层添加到了地图上,如图2-9所示。


<a href=https://yqfile.alicdn.com/e1c32b9c4d9c0401d8402e12477bb0461b28d2ec.png" >

使用ArcGISDynamicMapServiceLayer实例可以执行多种操作。显然,你可以创建地图来显示服务中的数据,你还可以查询服务图层中的数据、通过层定义控制特征显示、控制单个图层的可见性、设置时间相关信息、导出地图为图片、控制背景透明度和进行更多操作。

2.5.4 添加图层到地图
addLayer()方法接收一个图层(ArcGISDynamicMapServiceLayer或者ArcGISTiledMapServiceLayer)的实例作为第一个参数,一个可选索引指示图层放置的位置。下列示例代码创建了一个新的ArcGISDynamicMapServiceLayer实例指向服务的URL。然后调用Map.addLayer()并传递图层的一个新的实例。服务中的图层现在在地图上可见。

var operationalLayer = new ArcGISDynamicMapServiceLayer("http://sampleserver1. arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Population_World/MapServer");
map.addLayer(operationalLayer);

addLayer()方法接收图层对象数组并一次添加成功。

除了能够添加图层到地图外,还可以使用Map.removeLayer()或者Map.removeAllLayers()来从地图中移除某个或者所有图层。

2.5.5 地图服务设置可见图层

可以使用setVisibleLayers()方法控制动态地图服务中单个图层的可见性。该方法仅适用于动态地图服务图层,对切片地图服务图层则不适用。该方法接收一个整型数组,对应地图服务中的数据图层索引编号。

这个数组是从0开始的,因此地图服务中的第一个图层占据位置0。如图2-10所示,Demographics地图服务中Demographics/ESRI_Census_USA占据索引0。


f72e75ffdc5fdf661c7493a947d58d8ad2a876c4

因此,如果只想显示这个服务中的Census Block Points和Census Block Group图层的话,我们可以使用setVisibleLayers()方法,如下列代码所示。
var dynamicMapServiceLayer = new ArcGISDynamicMapServiceLayer("https://gis. sanantonio.gov/ArcGIS/rest/services/Demographics/MapServer");
dynamicMapServiceLayer.setVisibleLayers([1,2]);
map.addLayer(dynamicMapServiceLayer);
*```  
*2.5.6 设置定义表达式**
在ArcGISforDesktop中,可以使用定义表达式来限制数据图层特征的显示。一个定义表达式就是一个图层中针对行和列的简单SQL查询。仅满足查询条件的特征才会显示。如图2-11所示,假如只想显示人口大于100万的城市,表达式为POPULATION>1000000。ArcGIS API for JavaScript中包含setLayerDefinitions()方法接收适用于ArcGISDynamicMapServiceLayer来控制结果地图中特征显示的数组定义。下列示例代码展示了实现过程。
<div style="text-align: center">
 <img src=" https://yqfile.alicdn.com/e8873f7894d5e5fd76665506f98fa0ffc973a9cd.png" >
</div>

首先创建一个可容纳多个where语句的数组,它可以作为每个图层的定义表达式。在这种情况下,我们定义了第1个和第6个图层。数组是从0开始的,所以数组中的第一个就在索引0,where子句放到数组并传递到setLayerDefinitions()方法中,ArcGIS Server然后仅加载每个图层中满足where子句的特征。

**2.5.7 地图导航**
既然已掌握了一些关于地图和图层的知识,现在该学习如何在应用程序中控制地图导航了。在大多数情况下,用户需要能够通过平移和缩放特征来对地图进行导航操作。ArcGIS API for JavaScript提供一系列用户接口部件和工具栏,你可以用来允许用户通过使用缩放和平移特征来改变当前地图范围。地图导航还可以通过键盘和鼠标进行。除了这些用户接口部件和硬件接口外,地图导航还可以通过编程进行控制。

1.地图导航部件和工具栏
为应用程序提供地图导航控制功能的最简单的方式是添加各种部件和工具栏。当创建一个新地图和添加图层时,地图上已经包含了一个默认的缩放进度条。该进度条允许用户放大和缩小地图。缩放进度条如图2-12所示。让缩放进度条显示在地图中不需要你做任何的编程操作,默认它就是显示的。然而当创建一个Map对象实例时,如果有必要,你可以在应用程序中通过设置slider选项为false移除进度条。
<div style="text-align: center">
 <img src="https://yqfile.alicdn.com/943f33b58d5e2dd534d24f43896e96a0e0016491.png " >
</div>

{"slider":false,"nav":true,"opacity":0.5,"imageParameters":imageParameters}

你还可以添加平移按钮,当单击的时候地图会朝着箭头指向的方向平移。默认平移按钮不会出现在地图上。当创建Map对象时,你必须明确设定nav选项为true。

{"nav":true,"opacity":0.5,"imageParameters":imageParameters}

如图2-13所示为地图平移选项。
<div style="text-align: center">
 <img src="https://yqfile.alicdn.com/22cacdcb7bacd053e83099c7628cbadf64a270f9.png" >
</div>


ArcGISAPI for JavaScript还具备为应用程序添加多种类型的工具栏的能力,包括导航工具栏,如放大和缩小按钮、平移、全图、前一视图和后一视图。工具栏创建在后面章节会介绍到,所以我们会稍后讨论它。
<div style="text-align: center">
 <img src=" https://yqfile.alicdn.com/3cb4a61ebb5a27d878984c01265f0c9adf86c8c5.png" >
</div>

2.使用鼠标和键盘进行地图导航
用户可以使用鼠标和键盘设备来控制地图导航。用户默认可以进行下面这些操作。

- 拖拽鼠标平移。
- 鼠标向前滚动放大。
- 鼠标向后滚动缩小。
- 按住Shift键并拖拽鼠标放大。
- 按住Shift+Ctrl组合键并拖拽鼠标缩小。
- 按住Shift键并单击恢复居中。
- 双击居中并放大。
- 按住Shift键并双击居中和放大。
- 使用方向键进行平移。
- 使用+键放大一个级别。
- 使用−键缩小一个级别。

上面的选项可通过Map中的方法进行禁用。比如,要禁用滚轮缩放,你可以使用Map.disableScrollWheelZoom()方法。当地图加载后这些导航特征就可以移除掉。

3.获取和设置地图范围
我们要掌握的第一件事是获取和设置地图范围。应用程序中默认的初始地图范围是最后一次你在创建地图服务时保存的地图文档文件(.mxd)的范围。在某些情况下,这也许正是你需要的,但是如果需要设置默认外的地图范围的话,你也有其他选择。

一个可选参数是居中参数,可在Map对象的构造函数中定义。你可以使用这个可选参数结合缩放对象来设置地图范围。如下列代码,我们定义了地图的中心坐标并设置了缩放级别为3。

var map = new Map("mapDiv", {

    center: [-56.049, 38.485],
    zoom: 3,
    basemap: "streets"
  });
初始地图范围并不是一个必需参数,因此假如你忽略了该信息,地图会使用默认范围。下列代码显示的是仅指定了地图容器的ID。

var map = new Map("map");

当一个Map对象创建后,我们还可以传递一个Extent对象到Map.setExtent()方法中来改变范围,如下列代码所示。

var extent = new Extent(-95.271, 38.933, -95.228, 38.976);
map.setExtent(extent);

另外,你可以单独设置Extent的属性,如下列代码所示。

var extent = new Extent();
extent.xmin = -95.271;
extent.ymin = 38.933;
extent.xmax = -95.228;
extent.ymax = 38.976;
map.setExtent(extent);

有时应用程序中使用多地图服务,在这种情况下设置初始地图范围,无论是通过地图构造函数还是通过某个服务的Map.fullExtent()方法都可以完成设置。例如,常见的有提供包含航空影像的基础图层和包含本地操作数据源的服务结合的地图服务。

map = new Map("mapDiv", {extent:esri.geometry.geographicToWebMercator (myService2.fullExtent) });

网友评论

登录后评论
0/500
评论
异步社区
+ 关注