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

简介:

本节书摘来自异步社区《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) });

相关文章
|
1天前
|
开发框架 JavaScript 安全
WIndows Server 2016 部署 Web服务(简单篇)
WIndows Server 2016 部署 Web服务(简单篇)
|
1天前
|
数据采集 存储 XML
如何利用Python构建高效的Web爬虫
本文将介绍如何使用Python语言以及相关的库和工具,构建一个高效的Web爬虫。通过深入讨论爬虫的基本原理、常用的爬虫框架以及优化技巧,读者将能够了解如何编写可靠、高效的爬虫程序,实现数据的快速获取和处理。
|
5天前
|
JavaScript 前端开发 C++
【Web 前端】JavaScript window.onload 事件和 jQuery ready 函数有何不同?
【5月更文挑战第2天】【Web 前端】JavaScript window.onload 事件和 jQuery ready 函数有何不同?
|
7天前
|
运维 前端开发 JavaScript
【专栏:HTML进阶篇】HTML与Web标准:构建可访问与可维护的网页
【4月更文挑战第30天】本文探讨了HTML与Web标准的关系,强调遵循标准对创建高质量、可访问、可维护网页的重要性。通过使用语义化标签、提供文本替代、合理使用表格和列表,可提升网页可访问性;通过结构化文档、添加注释、分离结构与表现,能增强网页可维护性。遵循Web标准,可确保网页在不同设备上的兼容性,并满足各类用户需求。
|
7天前
|
开发框架 JavaScript 前端开发
【JavaScript 与 TypeScript 技术专栏】TypeScript 在 Web 开发中的前沿应用
【4月更文挑战第30天】TypeScript在Web开发中日益重要,以其强大的类型系统提升代码质量,支持组件化开发,与React、Vue、Angular等框架良好集成。在大型项目管理中,TypeScript助于代码组织和优化,提高团队协作效率。此外,它提升开发体验,提供智能提示和错误检测。众多成功案例证明其前沿应用,未来将在Web开发领域持续发挥关键作用。
|
7天前
|
移动开发 JavaScript 前端开发
【JavaScript技术专栏】Web Worker在JavaScript中的应用
【4月更文挑战第30天】HTML5的Web Worker API解决了JavaScript单线程性能瓶颈问题,允许在后台线程运行JS代码。本文介绍了Web Worker的基本概念、类型、用法和应用场景,如复杂计算、图像处理和数据同步。通过实例展示了搜索建议、游戏开发和实时数据分析等应用,并提醒注意其无法直接访问DOM、需消息传递通信以及移动端资源管理。Web Worker为前端开发提供了多线程能力,提升了Web应用性能和用户体验。
|
7天前
|
开发框架 Dart 前端开发
【Flutter前端技术开发专栏】Flutter中的Web支持:构建跨平台Web应用
【4月更文挑战第30天】Flutter,Google的开源跨平台框架,已延伸至Web领域,让开发者能用同一代码库构建移动和Web应用。Flutter Web通过将Dart代码编译成JavaScript和WASM运行在Web上。尽管性能可能不及原生Web应用,但适合交互性强、UI复杂的应用。开发者应关注性能优化、兼容性测试,并利用Flutter的声明式UI、热重载等优势。随着其发展,Flutter Web为跨平台开发带来更多潜力。
【Flutter前端技术开发专栏】Flutter中的Web支持:构建跨平台Web应用
|
7天前
|
JavaScript 前端开发 API
如何利用JavaScript和Electron构建具有丰富功能的桌面应用
【4月更文挑战第30天】如何利用JavaScript和Electron构建具有丰富功能的桌面应用
5 0
|
7天前
|
缓存 监控 JavaScript
Node.js中构建RESTful API的最佳实践
【4月更文挑战第30天】本文介绍了在Node.js中构建RESTful API的最佳实践:选择合适的框架(如Express、Koa)、设计清晰的API接口(遵循HTTP动词和资源路径)、实现认证授权(JWT、OAuth 2.0)、错误处理、限流缓存、编写文档和测试,以及监控性能优化。这些实践有助于创建健壮、可维护和易用的API。
|
7天前
|
消息中间件 监控 JavaScript
Node.js中的微服务架构:构建与实践
【4月更文挑战第30天】本文探讨了在Node.js中构建微服务的实践,包括定义服务边界、选择框架(如Express、Koa或NestJS)、设计RESTful API、实现服务间通信(HTTP、gRPC、消息队列)、错误处理、服务发现与负载均衡,以及监控和日志记录。微服务架构能提升应用的可伸缩性、灵活性和可维护性。