《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) });

相关文章
|
2天前
|
前端开发 安全 JavaScript
构建高效Web应用:前后端分离架构的实践
【9月更文挑战第4天】在数字时代,Web应用已成为企业与用户互动的主要平台。本文将介绍如何通过前后端分离的架构设计来构建高效的Web应用,探讨该架构的优势,并分享实现过程中的关键步骤和注意事项。文章旨在为开发者提供一种清晰、高效的开发模式,帮助其在快速变化的市场环境中保持竞争力。
|
6天前
|
中间件 编译器 数据处理
在web开发中应用管道过滤器
【9月更文挑战第1天】本文介绍管道-过滤器架构将数据处理流程分解为一系列独立组件,通过管道连接,适用于数据流处理如图像处理、编译器设计等。通过具体实例说明了Gin如何有效支持管道-过滤器风格的设计,构建高性能Web服务。
25 9
|
7天前
|
Rust 安全 开发者
惊爆!Xamarin 携手机器学习,开启智能应用新纪元,个性化体验与跨平台优势完美融合大揭秘!
【8月更文挑战第31天】随着互联网的发展,Web应用对性能和安全性要求不断提高。Rust凭借卓越的性能、内存安全及丰富生态,成为构建高性能Web服务器的理想选择。本文通过一个简单示例,展示如何使用Rust和Actix-web框架搭建基本Web服务器,从创建项目到运行服务器全程指导,帮助读者领略Rust在Web后端开发中的强大能力。通过实践,读者可以体验到Rust在性能和安全性方面的优势,以及其在Web开发领域的巨大潜力。
18 0
|
7天前
|
开发者 Java 前端开发
Struts 2验证框架:如何让数据校验成为Web开发的隐形守护者?揭秘前后端一致性的秘诀
【8月更文挑战第31天】在现代Web开发中,数据验证对确保应用健壮性和良好用户体验至关重要。随着前后端分离架构的普及,保证数据校验一致性尤为关键。Struts 2 验证框架基于 JavaBean 验证 API(JSR 303/JSR 380),允许开发者通过注解或 XML 配置轻松定义验证规则,确保输入数据在执行业务逻辑前已通过验证。此外,Struts 2 支持与前端 JavaScript 验证相结合,确保前后端数据校验一致,提升用户体验。通过注解、XML 配置和资源文件,开发者可以轻松定义和调整验证规则,实现前后端一致的数据校验,提高应用健壮性。
16 0
|
7天前
|
Java 缓存 数据库连接
揭秘!Struts 2性能翻倍的秘诀:不可思议的优化技巧大公开
【8月更文挑战第31天】《Struts 2性能优化技巧》介绍了提升Struts 2 Web应用响应速度的关键策略,包括减少配置开销、优化Action处理、合理使用拦截器、精简标签库使用、改进数据访问方式、利用缓存机制以及浏览器与网络层面的优化。通过实施这些技巧,如懒加载配置、异步请求处理、高效数据库连接管理和启用GZIP压缩等,可显著提高应用性能,为用户提供更快的体验。性能优化需根据实际场景持续调整。
29 0
|
7天前
|
Java 数据库连接 Spring
Struts 2 插件开发竟如魔法盛宴,为框架注入超能力,开启奇幻编程之旅!
【8月更文挑战第31天】在Web开发中,Struts 2插件开发允许我们在不改动框架核心代码的前提下,通过创建实现特定接口的Java类来扩展框架功能、调整其行为或促进与其他框架(如Spring、Hibernate)的集成,从而更好地满足特定业务需求。遵循良好的设计原则与实践,能够确保插件的高效稳定运行并提升整体项目的可维护性。具体步骤包括创建项目、定义插件类、实现初始化与销毁逻辑,并将插件部署至应用中。
28 0
|
7天前
|
Java 网络架构 数据格式
Struts 2 携手 RESTful:颠覆传统,重塑Web服务新纪元的史诗级组合!
【8月更文挑战第31天】《Struts 2 与 RESTful 设计:构建现代 Web 服务》介绍如何结合 Struts 2 框架与 RESTful 设计理念,构建高效、可扩展的 Web 服务。Struts 2 的 REST 插件提供简洁的 API 和约定,使开发者能快速创建符合 REST 规范的服务接口。通过在 `struts.xml` 中配置 `&lt;rest&gt;` 命名空间并使用注解如 `@Action`、`@GET` 等,可轻松定义服务路径及 HTTP 方法。
22 0
|
7天前
|
开发者 Java 开发框架
JSF与EJB,打造企业级应用的神器!让你的Web应用更加稳定、高效!
【8月更文挑战第31天】在现代企业级应用开发中,JSF(JavaServer Faces)与EJB(Enterprise JavaBeans)是两大核心技术。JSF作为一款基于Java的Web应用框架,以其丰富的UI组件和表单处理功能著称;EJB则专注于提供分布式事务处理及远程调用等企业级服务。两者的结合为企业应用带来了高效便捷的开发模式。下文将通过一个简单的示例展示如何利用JSF进行用户信息的输入与保存,并借助EJB实现相关业务逻辑。尽管这一组合具有明显优势,但在实际应用中还需考虑其局限性并作出合理选择。
18 0
|
7天前
|
开发者 安全 SQL
JSF安全卫士:打造铜墙铁壁,抵御Web攻击的钢铁防线!
【8月更文挑战第31天】在构建Web应用时,安全性至关重要。JavaServer Faces (JSF)作为流行的Java Web框架,需防范如XSS、CSRF及SQL注入等攻击。本文详细介绍了如何在JSF应用中实施安全措施,包括严格验证用户输入、使用安全编码实践、实施内容安全策略(CSP)及使用CSRF tokens等。通过示例代码和最佳实践,帮助开发者构建更安全的应用,保护用户数据和系统资源。
17 0
|
7天前
|
前端开发 API 开发者
JSF与RESTful服务的完美邂逅:如何打造符合现代Web潮流的数据交互新体验
【8月更文挑战第31天】随着互联网技术的发展,RESTful架构风格因其实现简便与无状态特性而在Web服务构建中日益流行。本文探讨如何结合JavaServer Faces (JSF) 和 JAX-RS 构建RESTful API,展示从前端到后端分离的完整解决方案。通过定义资源类、配置 `web.xml` 文件以及使用依赖注入等步骤,演示了在JSF项目中实现RESTful服务的具体过程,为Java开发者提供了实用指南。
17 0
下一篇
DDNS